1: <?php
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138:
139:
140: 141: 142: 143:
144: require_once(dirname(__FILE__).'/config/tcpdf_config.php');
145:
146: 147: 148:
149: define('PDF_PRODUCER', 'TCPDF 5.9.009 (http://www.tcpdf.org)');
150:
151: 152: 153: 154: 155: 156: 157: 158: 159: 160:
161: class TCPDF {
162:
163:
164:
165: 166: 167: 168:
169: protected $page;
170:
171: 172: 173: 174:
175: protected $n;
176:
177: 178: 179: 180:
181: protected $offsets;
182:
183: 184: 185: 186:
187: protected $buffer;
188:
189: 190: 191: 192:
193: protected $pages = array();
194:
195: 196: 197: 198:
199: protected $state;
200:
201: 202: 203: 204:
205: protected $compress;
206:
207: 208: 209: 210:
211: protected $CurOrientation;
212:
213: 214: 215: 216:
217: protected $pagedim = array();
218:
219: 220: 221: 222:
223: protected $k;
224:
225: 226: 227: 228:
229: protected $fwPt;
230:
231: 232: 233: 234:
235: protected $fhPt;
236:
237: 238: 239: 240:
241: protected $wPt;
242:
243: 244: 245: 246:
247: protected $hPt;
248:
249: 250: 251: 252:
253: protected $w;
254:
255: 256: 257: 258:
259: protected $h;
260:
261: 262: 263: 264:
265: protected $lMargin;
266:
267: 268: 269: 270:
271: protected $tMargin;
272:
273: 274: 275: 276:
277: protected $rMargin;
278:
279: 280: 281: 282:
283: protected $bMargin;
284:
285: 286: 287: 288: 289:
290: protected $cell_padding = array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0);
291:
292: 293: 294: 295: 296:
297: protected $cell_margin = array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0);
298:
299: 300: 301: 302:
303: protected $x;
304:
305: 306: 307: 308:
309: protected $y;
310:
311: 312: 313: 314:
315: protected $lasth;
316:
317: 318: 319: 320:
321: protected $LineWidth;
322:
323: 324: 325: 326:
327: protected $CoreFonts;
328:
329: 330: 331: 332:
333: protected $fonts = array();
334:
335: 336: 337: 338:
339: protected $FontFiles = array();
340:
341: 342: 343: 344:
345: protected $diffs = array();
346:
347: 348: 349: 350:
351: protected $images = array();
352:
353: 354: 355: 356:
357: protected $PageAnnots = array();
358:
359: 360: 361: 362:
363: protected $links = array();
364:
365: 366: 367: 368:
369: protected $FontFamily;
370:
371: 372: 373: 374:
375: protected $FontStyle;
376:
377: 378: 379: 380: 381:
382: protected $FontAscent;
383:
384: 385: 386: 387: 388:
389: protected $FontDescent;
390:
391: 392: 393: 394:
395: protected $underline;
396:
397: 398: 399: 400:
401: protected $overline;
402:
403: 404: 405: 406:
407: protected $CurrentFont;
408:
409: 410: 411: 412:
413: protected $FontSizePt;
414:
415: 416: 417: 418:
419: protected $FontSize;
420:
421: 422: 423: 424:
425: protected $DrawColor;
426:
427: 428: 429: 430:
431: protected $FillColor;
432:
433: 434: 435: 436:
437: protected $TextColor;
438:
439: 440: 441: 442:
443: protected $ColorFlag;
444:
445: 446: 447: 448:
449: protected $AutoPageBreak;
450:
451: 452: 453: 454:
455: protected $PageBreakTrigger;
456:
457: 458: 459: 460:
461: protected = false;
462:
463: 464: 465: 466:
467: protected $ZoomMode;
468:
469: 470: 471: 472:
473: protected $LayoutMode;
474:
475: 476: 477: 478:
479: protected $title = '';
480:
481: 482: 483: 484:
485: protected $subject = '';
486:
487: 488: 489: 490:
491: protected $author = '';
492:
493: 494: 495: 496:
497: protected $keywords = '';
498:
499: 500: 501: 502:
503: protected $creator = '';
504:
505: 506: 507: 508:
509: protected $AliasNbPages = '{nb}';
510:
511: 512: 513: 514:
515: protected $AliasNumPage = '{pnb}';
516:
517: 518: 519: 520: 521: 522:
523: protected $img_rb_x;
524:
525: 526: 527: 528: 529: 530:
531: protected $img_rb_y;
532:
533: 534: 535: 536: 537: 538:
539: protected $imgscale = 1;
540:
541: 542: 543: 544: 545: 546:
547: protected $isunicode = false;
548:
549: 550: 551: 552: 553: 554:
555: protected $unicode;
556:
557: 558: 559: 560: 561:
562: protected $PDFVersion = '1.7';
563:
564: 565: 566: 567:
568: protected ;
569:
570: 571: 572: 573:
574: protected ;
575:
576: 577: 578: 579: 580:
581: protected $original_lMargin;
582:
583: 584: 585: 586: 587:
588: protected $original_rMargin;
589:
590: 591: 592: 593:
594: protected ;
595:
596: 597: 598: 599:
600: protected ;
601:
602: 603: 604: 605:
606: protected $l;
607:
608: 609: 610: 611:
612: protected $barcode = false;
613:
614: 615: 616: 617:
618: protected = true;
619:
620: 621: 622: 623:
624: protected = true;
625:
626: 627: 628: 629:
630: protected = '';
631:
632: 633: 634: 635:
636: protected = 30;
637:
638: 639: 640: 641:
642: protected = '';
643:
644: 645: 646: 647:
648: protected = '';
649:
650: 651: 652: 653:
654: protected $default_table_columns = 4;
655:
656:
657:
658: 659: 660: 661:
662: protected $HREF = array();
663:
664: 665: 666: 667:
668: protected $fontlist = array();
669:
670: 671: 672: 673:
674: protected $fgcolor;
675:
676: 677: 678: 679:
680: protected $listordered = array();
681:
682: 683: 684: 685:
686: protected $listcount = array();
687:
688: 689: 690: 691:
692: protected $listnum = 0;
693:
694: 695: 696: 697:
698: protected $listindent = 0;
699:
700: 701: 702: 703:
704: protected $listindentlevel = 0;
705:
706: 707: 708: 709:
710: protected $bgcolor;
711:
712: 713: 714: 715:
716: protected $tempfontsize = 10;
717:
718: 719: 720: 721:
722: protected $lispacer = '';
723:
724: 725: 726: 727: 728:
729: protected $encoding = 'UTF-8';
730:
731: 732: 733: 734: 735:
736: protected $internal_encoding;
737:
738: 739: 740: 741: 742:
743: protected $rtl = false;
744:
745: 746: 747: 748: 749:
750: protected $tmprtl = false;
751:
752:
753:
754: 755: 756: 757: 758:
759: protected $encrypted;
760:
761: 762: 763: 764: 765:
766: protected $encryptdata = array();
767:
768: 769: 770: 771: 772:
773: protected $last_enc_key;
774:
775: 776: 777: 778: 779:
780: protected $last_enc_key_c;
781:
782: 783: 784: 785:
786: protected $enc_padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
787:
788: 789: 790: 791: 792:
793: protected $file_id;
794:
795:
796:
797: 798: 799: 800: 801:
802: protected $outlines = array();
803:
804: 805: 806: 807: 808:
809: protected $OutlineRoot;
810:
811:
812:
813: 814: 815: 816: 817:
818: protected $javascript = '';
819:
820: 821: 822: 823: 824:
825: protected $n_js;
826:
827: 828: 829: 830: 831:
832: protected $linethrough;
833:
834: 835: 836: 837: 838:
839: protected $ur = array();
840:
841: 842: 843: 844: 845:
846: protected $dpi = 72;
847:
848: 849: 850: 851: 852:
853: protected $newpagegroup = array();
854:
855: 856: 857: 858: 859:
860: protected $pagegroups;
861:
862: 863: 864: 865: 866:
867: protected $currpagegroup;
868:
869: 870: 871: 872: 873:
874: protected $visibility = 'all';
875:
876: 877: 878: 879: 880:
881: protected $n_ocg_print;
882:
883: 884: 885: 886: 887:
888: protected $n_ocg_view;
889:
890: 891: 892: 893: 894:
895: protected $extgstates;
896:
897: 898: 899: 900: 901:
902: protected $jpeg_quality;
903:
904: 905: 906: 907: 908:
909: protected $cell_height_ratio = K_CELL_HEIGHT_RATIO;
910:
911: 912: 913: 914: 915:
916: protected $viewer_preferences;
917:
918: 919: 920: 921: 922:
923: protected $PageMode;
924:
925: 926: 927: 928: 929:
930: protected $gradients = array();
931:
932: 933: 934: 935: 936: 937:
938: protected $intmrk = array();
939:
940: 941: 942: 943: 944: 945:
946: protected $bordermrk = array();
947:
948: 949: 950: 951: 952: 953:
954: protected $emptypagemrk = array();
955:
956: 957: 958: 959: 960: 961:
962: protected $cntmrk = array();
963:
964: 965: 966: 967: 968:
969: protected = array();
970:
971: 972: 973: 974: 975:
976: protected = array();
977:
978: 979: 980: 981: 982:
983: protected $newline = true;
984:
985: 986: 987: 988: 989:
990: protected $endlinex = 0;
991:
992: 993: 994: 995: 996:
997: protected $linestyleWidth = '';
998:
999: 1000: 1001: 1002: 1003:
1004: protected $linestyleCap = '0 J';
1005:
1006: 1007: 1008: 1009: 1010:
1011: protected $linestyleJoin = '0 j';
1012:
1013: 1014: 1015: 1016: 1017:
1018: protected $linestyleDash = '[] 0 d';
1019:
1020: 1021: 1022: 1023: 1024:
1025: protected $openMarkedContent = false;
1026:
1027: 1028: 1029: 1030: 1031:
1032: protected $htmlvspace = 0;
1033:
1034: 1035: 1036: 1037: 1038:
1039: protected $spot_colors = array();
1040:
1041: 1042: 1043: 1044: 1045:
1046: protected $lisymbol = '';
1047:
1048: 1049: 1050: 1051: 1052:
1053: protected $epsmarker = 'x#!#EPS#!#x';
1054:
1055: 1056: 1057: 1058: 1059:
1060: protected $transfmatrix = array();
1061:
1062: 1063: 1064: 1065: 1066:
1067: protected $transfmatrix_key = 0;
1068:
1069: 1070: 1071: 1072: 1073:
1074: protected $booklet = false;
1075:
1076: 1077: 1078: 1079: 1080:
1081: protected $feps = 0.005;
1082:
1083: 1084: 1085: 1086: 1087:
1088: protected $tagvspaces = array();
1089:
1090: 1091: 1092: 1093: 1094: 1095:
1096: protected $customlistindent = -1;
1097:
1098: 1099: 1100: 1101: 1102:
1103: protected $opencell = true;
1104:
1105: 1106: 1107: 1108: 1109:
1110: protected $embeddedfiles = array();
1111:
1112: 1113: 1114: 1115: 1116:
1117: protected $premode = false;
1118:
1119: 1120: 1121: 1122: 1123: 1124:
1125: protected $transfmrk = array();
1126:
1127: 1128: 1129: 1130: 1131:
1132: protected $htmlLinkColorArray = array(0, 0, 255);
1133:
1134: 1135: 1136: 1137: 1138:
1139: protected $htmlLinkFontStyle = 'U';
1140:
1141: 1142: 1143: 1144: 1145:
1146: protected $numpages = 0;
1147:
1148: 1149: 1150: 1151: 1152:
1153: protected $pagelen = array();
1154:
1155: 1156: 1157: 1158: 1159:
1160: protected $numimages = 0;
1161:
1162: 1163: 1164: 1165: 1166:
1167: protected $imagekeys = array();
1168:
1169: 1170: 1171: 1172: 1173:
1174: protected $bufferlen = 0;
1175:
1176: 1177: 1178: 1179: 1180:
1181: protected $diskcache = false;
1182:
1183: 1184: 1185: 1186: 1187:
1188: protected $numfonts = 0;
1189:
1190: 1191: 1192: 1193: 1194:
1195: protected $fontkeys = array();
1196:
1197: 1198: 1199: 1200: 1201:
1202: protected $font_obj_ids = array();
1203:
1204: 1205: 1206: 1207: 1208:
1209: protected $pageopen = array();
1210:
1211: 1212: 1213: 1214: 1215:
1216: protected $default_monospaced_font = 'courier';
1217:
1218: 1219: 1220: 1221: 1222:
1223: protected $objcopy;
1224:
1225: 1226: 1227: 1228: 1229:
1230: protected $cache_file_length = array();
1231:
1232: 1233: 1234: 1235: 1236:
1237: protected $thead = '';
1238:
1239: 1240: 1241: 1242: 1243:
1244: protected $theadMargins = array();
1245:
1246: 1247: 1248: 1249: 1250:
1251: protected $cache_UTF8StringToArray = array();
1252:
1253: 1254: 1255: 1256: 1257:
1258: protected $cache_maxsize_UTF8StringToArray = 8;
1259:
1260: 1261: 1262: 1263: 1264:
1265: protected $cache_size_UTF8StringToArray = 0;
1266:
1267: 1268: 1269: 1270: 1271:
1272: protected $sign = false;
1273:
1274: 1275: 1276: 1277: 1278:
1279: protected $signature_data = array();
1280:
1281: 1282: 1283: 1284: 1285:
1286: protected $signature_max_length = 11742;
1287:
1288: 1289: 1290: 1291: 1292:
1293: protected $signature_appearance = array('page' => 1, 'rect' => '0 0 0 0');
1294:
1295: 1296: 1297: 1298: 1299:
1300: protected $re_spaces = '/[^\S\xa0]/';
1301:
1302: 1303: 1304: 1305: 1306:
1307: protected $re_space = array('p' => '[^\S\xa0]', 'm' => '');
1308:
1309: 1310: 1311: 1312: 1313:
1314: protected $sig_obj_id = 0;
1315:
1316: 1317: 1318: 1319: 1320:
1321: protected $byterange_string = '/ByteRange[0 ********** ********** **********]';
1322:
1323: 1324: 1325: 1326: 1327:
1328: protected $sig_annot_ref = '***SIGANNREF*** 0 R';
1329:
1330: 1331: 1332: 1333: 1334:
1335: protected $page_obj_id = array();
1336:
1337: 1338: 1339: 1340: 1341:
1342: protected $form_obj_id = array();
1343:
1344: 1345: 1346: 1347: 1348:
1349: protected $default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128));
1350:
1351: 1352: 1353: 1354: 1355:
1356: protected $js_objects = array();
1357:
1358: 1359: 1360: 1361: 1362:
1363: protected $form_action = '';
1364:
1365: 1366: 1367: 1368: 1369:
1370: protected $form_enctype = 'application/x-www-form-urlencoded';
1371:
1372: 1373: 1374: 1375: 1376:
1377: protected $form_mode = 'post';
1378:
1379: 1380: 1381: 1382: 1383:
1384: protected $annotation_fonts = array();
1385:
1386: 1387: 1388: 1389: 1390:
1391: protected $radiobutton_groups = array();
1392:
1393: 1394: 1395: 1396: 1397:
1398: protected $radio_groups = array();
1399:
1400: 1401: 1402: 1403: 1404:
1405: protected $textindent = 0;
1406:
1407: 1408: 1409: 1410: 1411:
1412: protected $start_transaction_page = 0;
1413:
1414: 1415: 1416: 1417: 1418:
1419: protected $start_transaction_y = 0;
1420:
1421: 1422: 1423: 1424: 1425:
1426: protected $inthead = false;
1427:
1428: 1429: 1430: 1431: 1432:
1433: protected $columns = array();
1434:
1435: 1436: 1437: 1438: 1439:
1440: protected $num_columns = 1;
1441:
1442: 1443: 1444: 1445: 1446:
1447: protected $current_column = 0;
1448:
1449: 1450: 1451: 1452: 1453:
1454: protected $column_start_page = 0;
1455:
1456: 1457: 1458: 1459: 1460:
1461: protected $maxselcol = array('page' => 0, 'column' => 0);
1462:
1463: 1464: 1465: 1466: 1467:
1468: protected $colxshift = array('x' => 0, 's' => 0, 'p' => 0);
1469:
1470: 1471: 1472: 1473: 1474:
1475: protected $textrendermode = 0;
1476:
1477: 1478: 1479: 1480: 1481:
1482: protected $textstrokewidth = 0;
1483:
1484: 1485: 1486: 1487: 1488:
1489: protected $strokecolor;
1490:
1491: 1492: 1493: 1494: 1495:
1496: protected $pdfunit = 'mm';
1497:
1498: 1499: 1500: 1501:
1502: protected $tocpage = false;
1503:
1504: 1505: 1506: 1507: 1508:
1509: protected $rasterize_vector_images = false;
1510:
1511: 1512: 1513: 1514: 1515:
1516: protected $font_subsetting = true;
1517:
1518: 1519: 1520: 1521: 1522:
1523: protected $default_graphic_vars = array();
1524:
1525: 1526: 1527: 1528: 1529:
1530: protected $xobjects = array();
1531:
1532: 1533: 1534: 1535: 1536:
1537: protected $inxobj = false;
1538:
1539: 1540: 1541: 1542: 1543:
1544: protected $xobjid = '';
1545:
1546: 1547: 1548: 1549: 1550:
1551: protected $font_stretching = 100;
1552:
1553: 1554: 1555: 1556: 1557:
1558: protected $font_spacing = 0;
1559:
1560: 1561: 1562: 1563: 1564: 1565:
1566: protected $page_regions = array();
1567:
1568: 1569: 1570: 1571: 1572:
1573: protected $webcolor = array();
1574:
1575: 1576: 1577: 1578: 1579:
1580: protected $svgdir = '';
1581:
1582: 1583: 1584: 1585: 1586:
1587: protected $svgunit = 'px';
1588:
1589: 1590: 1591: 1592: 1593:
1594: protected $svggradients = array();
1595:
1596: 1597: 1598: 1599: 1600:
1601: protected $svggradientid = 0;
1602:
1603: 1604: 1605: 1606: 1607:
1608: protected $svgdefsmode = false;
1609:
1610: 1611: 1612: 1613: 1614:
1615: protected $svgdefs = array();
1616:
1617: 1618: 1619: 1620: 1621:
1622: protected $svgclipmode = false;
1623:
1624: 1625: 1626: 1627: 1628:
1629: protected $svgclippaths = array();
1630:
1631: 1632: 1633: 1634: 1635:
1636: protected $svgcliptm = array();
1637:
1638: 1639: 1640: 1641: 1642:
1643: protected $svgclipid = 0;
1644:
1645: 1646: 1647: 1648: 1649:
1650: protected $svgtext = '';
1651:
1652: 1653: 1654: 1655: 1656:
1657: protected $svgtextmode = array();
1658:
1659: 1660: 1661: 1662: 1663:
1664: protected $svginheritprop = array('clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cursor', 'direction', 'fill', 'fill-opacity', 'fill-rule', 'font', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'image-rendering', 'kerning', 'letter-spacing', 'marker', 'marker-end', 'marker-mid', 'marker-start', 'pointer-events', 'shape-rendering', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-rendering', 'visibility', 'word-spacing', 'writing-mode');
1665:
1666: 1667: 1668: 1669: 1670:
1671: protected $svgstyles = array(array(
1672: 'alignment-baseline' => 'auto',
1673: 'baseline-shift' => 'baseline',
1674: 'clip' => 'auto',
1675: 'clip-path' => 'none',
1676: 'clip-rule' => 'nonzero',
1677: 'color' => 'black',
1678: 'color-interpolation' => 'sRGB',
1679: 'color-interpolation-filters' => 'linearRGB',
1680: 'color-profile' => 'auto',
1681: 'color-rendering' => 'auto',
1682: 'cursor' => 'auto',
1683: 'direction' => 'ltr',
1684: 'display' => 'inline',
1685: 'dominant-baseline' => 'auto',
1686: 'enable-background' => 'accumulate',
1687: 'fill' => 'black',
1688: 'fill-opacity' => 1,
1689: 'fill-rule' => 'nonzero',
1690: 'filter' => 'none',
1691: 'flood-color' => 'black',
1692: 'flood-opacity' => 1,
1693: 'font' => '',
1694: 'font-family' => 'helvetica',
1695: 'font-size' => 'medium',
1696: 'font-size-adjust' => 'none',
1697: 'font-stretch' => 'normal',
1698: 'font-style' => 'normal',
1699: 'font-variant' => 'normal',
1700: 'font-weight' => 'normal',
1701: 'glyph-orientation-horizontal' => '0deg',
1702: 'glyph-orientation-vertical' => 'auto',
1703: 'image-rendering' => 'auto',
1704: 'kerning' => 'auto',
1705: 'letter-spacing' => 'normal',
1706: 'lighting-color' => 'white',
1707: 'marker' => '',
1708: 'marker-end' => 'none',
1709: 'marker-mid' => 'none',
1710: 'marker-start' => 'none',
1711: 'mask' => 'none',
1712: 'opacity' => 1,
1713: 'overflow' => 'auto',
1714: 'pointer-events' => 'visiblePainted',
1715: 'shape-rendering' => 'auto',
1716: 'stop-color' => 'black',
1717: 'stop-opacity' => 1,
1718: 'stroke' => 'none',
1719: 'stroke-dasharray' => 'none',
1720: 'stroke-dashoffset' => 0,
1721: 'stroke-linecap' => 'butt',
1722: 'stroke-linejoin' => 'miter',
1723: 'stroke-miterlimit' => 4,
1724: 'stroke-opacity' => 1,
1725: 'stroke-width' => 1,
1726: 'text-anchor' => 'start',
1727: 'text-decoration' => 'none',
1728: 'text-rendering' => 'auto',
1729: 'unicode-bidi' => 'normal',
1730: 'visibility' => 'visible',
1731: 'word-spacing' => 'normal',
1732: 'writing-mode' => 'lr-tb',
1733: 'text-color' => 'black',
1734: 'transfmatrix' => array(1, 0, 0, 1, 0, 0)
1735: ));
1736:
1737:
1738:
1739:
1740:
1741: 1742: 1743: 1744: 1745: 1746: 1747: 1748: 1749: 1750: 1751: 1752:
1753: public function __construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false) {
1754:
1755: if (function_exists('mb_internal_encoding') AND mb_internal_encoding()) {
1756: $this->internal_encoding = mb_internal_encoding();
1757: mb_internal_encoding('ASCII');
1758: }
1759: require(dirname(__FILE__).'/htmlcolors.php');
1760: $this->webcolor = $webcolor;
1761: require_once(dirname(__FILE__).'/unicode_data.php');
1762: $this->unicode = new TCPDF_UNICODE_DATA();
1763: $this->font_obj_ids = array();
1764: $this->page_obj_id = array();
1765: $this->form_obj_id = array();
1766:
1767: $this->diskcache = $diskcache ? true : false;
1768:
1769: $this->rtl = false;
1770: $this->tmprtl = false;
1771:
1772: $this->_dochecks();
1773:
1774: $this->isunicode = $unicode;
1775: $this->page = 0;
1776: $this->transfmrk[0] = array();
1777: $this->pagedim = array();
1778: $this->n = 2;
1779: $this->buffer = '';
1780: $this->pages = array();
1781: $this->state = 0;
1782: $this->fonts = array();
1783: $this->FontFiles = array();
1784: $this->diffs = array();
1785: $this->images = array();
1786: $this->links = array();
1787: $this->gradients = array();
1788: $this->InFooter = false;
1789: $this->lasth = 0;
1790: $this->FontFamily = 'helvetica';
1791: $this->FontStyle = '';
1792: $this->FontSizePt = 12;
1793: $this->underline = false;
1794: $this->overline = false;
1795: $this->linethrough = false;
1796: $this->DrawColor = '0 G';
1797: $this->FillColor = '0 g';
1798: $this->TextColor = '0 g';
1799: $this->ColorFlag = false;
1800:
1801: $this->encrypted = false;
1802: $this->last_enc_key = '';
1803:
1804: $this->CoreFonts = array(
1805: 'courier'=>'Courier',
1806: 'courierB'=>'Courier-Bold',
1807: 'courierI'=>'Courier-Oblique',
1808: 'courierBI'=>'Courier-BoldOblique',
1809: 'helvetica'=>'Helvetica',
1810: 'helveticaB'=>'Helvetica-Bold',
1811: 'helveticaI'=>'Helvetica-Oblique',
1812: 'helveticaBI'=>'Helvetica-BoldOblique',
1813: 'times'=>'Times-Roman',
1814: 'timesB'=>'Times-Bold',
1815: 'timesI'=>'Times-Italic',
1816: 'timesBI'=>'Times-BoldItalic',
1817: 'symbol'=>'Symbol',
1818: 'zapfdingbats'=>'ZapfDingbats'
1819: );
1820:
1821: $this->setPageUnit($unit);
1822:
1823: $this->setPageFormat($format, $orientation);
1824:
1825: $margin = 28.35 / $this->k;
1826: $this->SetMargins($margin, $margin);
1827:
1828: $cpadding = $margin / 10;
1829: $this->setCellPaddings($cpadding, 0, $cpadding, 0);
1830:
1831: $this->setCellMargins(0, 0, 0, 0);
1832:
1833: $this->LineWidth = 0.57 / $this->k;
1834: $this->linestyleWidth = sprintf('%.2F w', ($this->LineWidth * $this->k));
1835: $this->linestyleCap = '0 J';
1836: $this->linestyleJoin = '0 j';
1837: $this->linestyleDash = '[] 0 d';
1838:
1839: $this->SetAutoPageBreak(true, (2 * $margin));
1840:
1841: $this->SetDisplayMode('fullwidth');
1842:
1843: $this->SetCompression(true);
1844:
1845: $this->PDFVersion = '1.7';
1846: $this->encoding = $encoding;
1847: $this->HREF = array();
1848: $this->getFontsList();
1849: $this->fgcolor = array('R' => 0, 'G' => 0, 'B' => 0);
1850: $this->strokecolor = array('R' => 0, 'G' => 0, 'B' => 0);
1851: $this->bgcolor = array('R' => 255, 'G' => 255, 'B' => 255);
1852: $this->extgstates = array();
1853:
1854: $this->sign = false;
1855: $this->ur['enabled'] = false;
1856: $this->ur['document'] = '/FullSave';
1857: $this->ur['annots'] = '/Create/Delete/Modify/Copy/Import/Export';
1858: $this->ur['form'] = '/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate';
1859: $this->ur['signature'] = '/Modify';
1860: $this->ur['ef'] = '/Create/Delete/Modify/Import';
1861: $this->ur['formex'] = '';
1862: $this->signature_appearance = array('page' => 1, 'rect' => '0 0 0 0');
1863:
1864: $this->jpeg_quality = 75;
1865:
1866: $this->utf8Bidi(array(''), '');
1867:
1868: $this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt);
1869:
1870: if ($this->isunicode AND (@preg_match('/\pL/u', 'a') == 1)) {
1871:
1872:
1873:
1874:
1875:
1876: $this->setSpacesRE('/[^\S\P{Z}\xa0]/u');
1877: } else {
1878:
1879: $this->setSpacesRE('/[^\S\xa0]/');
1880: }
1881: $this->default_form_prop = array('lineWidth'=>1, 'borderStyle'=>'solid', 'fillColor'=>array(255, 255, 255), 'strokeColor'=>array(128, 128, 128));
1882:
1883: $this->file_id = md5($this->getRandomSeed('TCPDF'.$orientation.$unit.$format.$encoding));
1884:
1885: $this->default_graphic_vars = $this->getGraphicVars();
1886: }
1887:
1888: 1889: 1890: 1891: 1892:
1893: public function __destruct() {
1894:
1895: if (isset($this->internal_encoding) AND !empty($this->internal_encoding)) {
1896: mb_internal_encoding($this->internal_encoding);
1897: }
1898:
1899: $this->_destroy(true);
1900: }
1901:
1902: 1903: 1904: 1905: 1906: 1907:
1908: public function setPageUnit($unit) {
1909: $unit = strtolower($unit);
1910:
1911: switch ($unit) {
1912:
1913: case 'px':
1914: case 'pt': {
1915: $this->k = 1;
1916: break;
1917: }
1918:
1919: case 'mm': {
1920: $this->k = $this->dpi / 25.4;
1921: break;
1922: }
1923:
1924: case 'cm': {
1925: $this->k = $this->dpi / 2.54;
1926: break;
1927: }
1928:
1929: case 'in': {
1930: $this->k = $this->dpi;
1931: break;
1932: }
1933:
1934: default : {
1935: $this->Error('Incorrect unit: '.$unit);
1936: break;
1937: }
1938: }
1939: $this->pdfunit = $unit;
1940: if (isset($this->CurOrientation)) {
1941: $this->setPageOrientation($this->CurOrientation);
1942: }
1943: }
1944:
1945: 1946: 1947: 1948: 1949: 1950: 1951: 1952: 1953: 1954: 1955: 1956: 1957: 1958: 1959: 1960: 1961: 1962: 1963: 1964: 1965: 1966: 1967: 1968: 1969: 1970: 1971: 1972: 1973: 1974: 1975: 1976: 1977: 1978: 1979: 1980: 1981: 1982: 1983: 1984: 1985: 1986: 1987: 1988: 1989: 1990: 1991: 1992: 1993: 1994: 1995: 1996: 1997: 1998: 1999: 2000: 2001: 2002: 2003: 2004: 2005: 2006: 2007: 2008: 2009: 2010: 2011: 2012: 2013: 2014: 2015: 2016: 2017: 2018: 2019: 2020: 2021: 2022: 2023: 2024: 2025: 2026: 2027: 2028: 2029: 2030: 2031: 2032: 2033: 2034: 2035: 2036: 2037: 2038: 2039: 2040: 2041: 2042: 2043: 2044: 2045: 2046: 2047: 2048: 2049: 2050: 2051: 2052: 2053: 2054: 2055: 2056: 2057: 2058: 2059: 2060: 2061: 2062: 2063: 2064: 2065: 2066: 2067: 2068: 2069: 2070: 2071: 2072: 2073: 2074: 2075: 2076: 2077: 2078: 2079: 2080: 2081: 2082: 2083: 2084: 2085: 2086: 2087: 2088: 2089: 2090: 2091: 2092: 2093: 2094: 2095: 2096: 2097: 2098: 2099: 2100: 2101: 2102: 2103: 2104: 2105: 2106: 2107: 2108: 2109: 2110: 2111: 2112: 2113: 2114: 2115: 2116: 2117: 2118: 2119: 2120: 2121: 2122: 2123: 2124: 2125: 2126: 2127: 2128: 2129: 2130: 2131: 2132: 2133: 2134: 2135: 2136: 2137: 2138: 2139: 2140: 2141: 2142: 2143: 2144: 2145: 2146: 2147: 2148: 2149: 2150: 2151: 2152: 2153: 2154: 2155: 2156: 2157: 2158: 2159: 2160: 2161: 2162: 2163: 2164: 2165: 2166: 2167: 2168: 2169: 2170: 2171: 2172: 2173: 2174: 2175: 2176: 2177: 2178: 2179: 2180: 2181: 2182: 2183: 2184: 2185: 2186: 2187: 2188: 2189: 2190: 2191: 2192: 2193: 2194: 2195: 2196: 2197: 2198: 2199: 2200: 2201: 2202: 2203: 2204: 2205: 2206: 2207: 2208: 2209: 2210: 2211: 2212: 2213: 2214: 2215: 2216: 2217: 2218: 2219: 2220: 2221: 2222: 2223: 2224: 2225: 2226: 2227: 2228: 2229: 2230: 2231: 2232: 2233: 2234: 2235: 2236: 2237: 2238: 2239: 2240: 2241: 2242: 2243: 2244: 2245: 2246: 2247: 2248: 2249: 2250: 2251: 2252: 2253: 2254: 2255: 2256: 2257: 2258:
2259: public function getPageSizeFromFormat($format) {
2260:
2261: switch (strtoupper($format)) {
2262:
2263: case 'A0' : {$pf = array( 2383.937, 3370.394); break;}
2264: case 'A1' : {$pf = array( 1683.780, 2383.937); break;}
2265: case 'A2' : {$pf = array( 1190.551, 1683.780); break;}
2266: case 'A3' : {$pf = array( 841.890, 1190.551); break;}
2267: case 'A4' : {$pf = array( 595.276, 841.890); break;}
2268: case 'A5' : {$pf = array( 419.528, 595.276); break;}
2269: case 'A6' : {$pf = array( 297.638, 419.528); break;}
2270: case 'A7' : {$pf = array( 209.764, 297.638); break;}
2271: case 'A8' : {$pf = array( 147.402, 209.764); break;}
2272: case 'A9' : {$pf = array( 104.882, 147.402); break;}
2273: case 'A10': {$pf = array( 73.701, 104.882); break;}
2274: case 'A11': {$pf = array( 51.024, 73.701); break;}
2275: case 'A12': {$pf = array( 36.850, 51.024); break;}
2276:
2277: case 'B0' : {$pf = array( 2834.646, 4008.189); break;}
2278: case 'B1' : {$pf = array( 2004.094, 2834.646); break;}
2279: case 'B2' : {$pf = array( 1417.323, 2004.094); break;}
2280: case 'B3' : {$pf = array( 1000.630, 1417.323); break;}
2281: case 'B4' : {$pf = array( 708.661, 1000.630); break;}
2282: case 'B5' : {$pf = array( 498.898, 708.661); break;}
2283: case 'B6' : {$pf = array( 354.331, 498.898); break;}
2284: case 'B7' : {$pf = array( 249.449, 354.331); break;}
2285: case 'B8' : {$pf = array( 175.748, 249.449); break;}
2286: case 'B9' : {$pf = array( 124.724, 175.748); break;}
2287: case 'B10': {$pf = array( 87.874, 124.724); break;}
2288: case 'B11': {$pf = array( 62.362, 87.874); break;}
2289: case 'B12': {$pf = array( 42.520, 62.362); break;}
2290:
2291: case 'C0' : {$pf = array( 2599.370, 3676.535); break;}
2292: case 'C1' : {$pf = array( 1836.850, 2599.370); break;}
2293: case 'C2' : {$pf = array( 1298.268, 1836.850); break;}
2294: case 'C3' : {$pf = array( 918.425, 1298.268); break;}
2295: case 'C4' : {$pf = array( 649.134, 918.425); break;}
2296: case 'C5' : {$pf = array( 459.213, 649.134); break;}
2297: case 'C6' : {$pf = array( 323.150, 459.213); break;}
2298: case 'C7' : {$pf = array( 229.606, 323.150); break;}
2299: case 'C8' : {$pf = array( 161.575, 229.606); break;}
2300: case 'C9' : {$pf = array( 113.386, 161.575); break;}
2301: case 'C10': {$pf = array( 79.370, 113.386); break;}
2302: case 'C11': {$pf = array( 56.693, 79.370); break;}
2303: case 'C12': {$pf = array( 39.685, 56.693); break;}
2304: case 'C76': {$pf = array( 229.606, 459.213); break;}
2305: case 'DL' : {$pf = array( 311.811, 623.622); break;}
2306:
2307: case 'E0' : {$pf = array( 2491.654, 3517.795); break;}
2308: case 'E1' : {$pf = array( 1757.480, 2491.654); break;}
2309: case 'E2' : {$pf = array( 1247.244, 1757.480); break;}
2310: case 'E3' : {$pf = array( 878.740, 1247.244); break;}
2311: case 'E4' : {$pf = array( 623.622, 878.740); break;}
2312: case 'E5' : {$pf = array( 439.370, 623.622); break;}
2313: case 'E6' : {$pf = array( 311.811, 439.370); break;}
2314: case 'E7' : {$pf = array( 221.102, 311.811); break;}
2315: case 'E8' : {$pf = array( 155.906, 221.102); break;}
2316: case 'E9' : {$pf = array( 110.551, 155.906); break;}
2317: case 'E10': {$pf = array( 76.535, 110.551); break;}
2318: case 'E11': {$pf = array( 53.858, 76.535); break;}
2319: case 'E12': {$pf = array( 36.850, 53.858); break;}
2320:
2321: case 'G0' : {$pf = array( 2715.591, 3838.110); break;}
2322: case 'G1' : {$pf = array( 1919.055, 2715.591); break;}
2323: case 'G2' : {$pf = array( 1357.795, 1919.055); break;}
2324: case 'G3' : {$pf = array( 958.110, 1357.795); break;}
2325: case 'G4' : {$pf = array( 677.480, 958.110); break;}
2326: case 'G5' : {$pf = array( 479.055, 677.480); break;}
2327: case 'G6' : {$pf = array( 337.323, 479.055); break;}
2328: case 'G7' : {$pf = array( 238.110, 337.323); break;}
2329: case 'G8' : {$pf = array( 167.244, 238.110); break;}
2330: case 'G9' : {$pf = array( 119.055, 167.244); break;}
2331: case 'G10': {$pf = array( 82.205, 119.055); break;}
2332: case 'G11': {$pf = array( 59.528, 82.205); break;}
2333: case 'G12': {$pf = array( 39.685, 59.528); break;}
2334:
2335: case 'RA0': {$pf = array( 2437.795, 3458.268); break;}
2336: case 'RA1': {$pf = array( 1729.134, 2437.795); break;}
2337: case 'RA2': {$pf = array( 1218.898, 1729.134); break;}
2338: case 'RA3': {$pf = array( 864.567, 1218.898); break;}
2339: case 'RA4': {$pf = array( 609.449, 864.567); break;}
2340: case 'SRA0': {$pf = array( 2551.181, 3628.346); break;}
2341: case 'SRA1': {$pf = array( 1814.173, 2551.181); break;}
2342: case 'SRA2': {$pf = array( 1275.591, 1814.173); break;}
2343: case 'SRA3': {$pf = array( 907.087, 1275.591); break;}
2344: case 'SRA4': {$pf = array( 637.795, 907.087); break;}
2345:
2346: case '4A0': {$pf = array( 4767.874, 6740.787); break;}
2347: case '2A0': {$pf = array( 3370.394, 4767.874); break;}
2348:
2349: case 'A2_EXTRA' : {$pf = array( 1261.417, 1754.646); break;}
2350: case 'A3+' : {$pf = array( 932.598, 1369.134); break;}
2351: case 'A3_EXTRA' : {$pf = array( 912.756, 1261.417); break;}
2352: case 'A3_SUPER' : {$pf = array( 864.567, 1440.000); break;}
2353: case 'SUPER_A3' : {$pf = array( 864.567, 1380.472); break;}
2354: case 'A4_EXTRA' : {$pf = array( 666.142, 912.756); break;}
2355: case 'A4_SUPER' : {$pf = array( 649.134, 912.756); break;}
2356: case 'SUPER_A4' : {$pf = array( 643.465, 1009.134); break;}
2357: case 'A4_LONG' : {$pf = array( 595.276, 986.457); break;}
2358: case 'F4' : {$pf = array( 595.276, 935.433); break;}
2359: case 'SO_B5_EXTRA': {$pf = array( 572.598, 782.362); break;}
2360: case 'A5_EXTRA' : {$pf = array( 490.394, 666.142); break;}
2361:
2362: case 'ANSI_E': {$pf = array( 2448.000, 3168.000); break;}
2363: case 'ANSI_D': {$pf = array( 1584.000, 2448.000); break;}
2364: case 'ANSI_C': {$pf = array( 1224.000, 1584.000); break;}
2365: case 'ANSI_B': {$pf = array( 792.000, 1224.000); break;}
2366: case 'ANSI_A': {$pf = array( 612.000, 792.000); break;}
2367:
2368: case 'USLEDGER':
2369: case 'LEDGER' : {$pf = array( 1224.000, 792.000); break;}
2370: case 'ORGANIZERK':
2371: case 'BIBLE':
2372: case 'USTABLOID':
2373: case 'TABLOID': {$pf = array( 792.000, 1224.000); break;}
2374: case 'ORGANIZERM':
2375: case 'USLETTER':
2376: case 'LETTER' : {$pf = array( 612.000, 792.000); break;}
2377: case 'USLEGAL':
2378: case 'LEGAL' : {$pf = array( 612.000, 1008.000); break;}
2379: case 'GOVERNMENTLETTER':
2380: case 'GLETTER': {$pf = array( 576.000, 756.000); break;}
2381: case 'JUNIORLEGAL':
2382: case 'JLEGAL' : {$pf = array( 576.000, 360.000); break;}
2383:
2384: case 'QUADDEMY': {$pf = array( 2520.000, 3240.000); break;}
2385: case 'SUPER_B': {$pf = array( 936.000, 1368.000); break;}
2386: case 'QUARTO': {$pf = array( 648.000, 792.000); break;}
2387: case 'GOVERNMENTLEGAL':
2388: case 'FOLIO': {$pf = array( 612.000, 936.000); break;}
2389: case 'MONARCH':
2390: case 'EXECUTIVE': {$pf = array( 522.000, 756.000); break;}
2391: case 'ORGANIZERL':
2392: case 'STATEMENT':
2393: case 'MEMO': {$pf = array( 396.000, 612.000); break;}
2394: case 'FOOLSCAP': {$pf = array( 595.440, 936.000); break;}
2395: case 'COMPACT': {$pf = array( 306.000, 486.000); break;}
2396: case 'ORGANIZERJ': {$pf = array( 198.000, 360.000); break;}
2397:
2398: case 'P1': {$pf = array( 1587.402, 2437.795); break;}
2399: case 'P2': {$pf = array( 1218.898, 1587.402); break;}
2400: case 'P3': {$pf = array( 793.701, 1218.898); break;}
2401: case 'P4': {$pf = array( 609.449, 793.701); break;}
2402: case 'P5': {$pf = array( 396.850, 609.449); break;}
2403: case 'P6': {$pf = array( 303.307, 396.850); break;}
2404:
2405: case 'ARCH_E' : {$pf = array( 2592.000, 3456.000); break;}
2406: case 'ARCH_E1': {$pf = array( 2160.000, 3024.000); break;}
2407: case 'ARCH_D' : {$pf = array( 1728.000, 2592.000); break;}
2408: case 'BROADSHEET':
2409: case 'ARCH_C' : {$pf = array( 1296.000, 1728.000); break;}
2410: case 'ARCH_B' : {$pf = array( 864.000, 1296.000); break;}
2411: case 'ARCH_A' : {$pf = array( 648.000, 864.000); break;}
2412:
2413:
2414: case 'ANNENV_A2' : {$pf = array( 314.640, 414.000); break;}
2415: case 'ANNENV_A6' : {$pf = array( 342.000, 468.000); break;}
2416: case 'ANNENV_A7' : {$pf = array( 378.000, 522.000); break;}
2417: case 'ANNENV_A8' : {$pf = array( 396.000, 584.640); break;}
2418: case 'ANNENV_A10' : {$pf = array( 450.000, 692.640); break;}
2419: case 'ANNENV_SLIM': {$pf = array( 278.640, 638.640); break;}
2420:
2421: case 'COMMENV_N6_1/4': {$pf = array( 252.000, 432.000); break;}
2422: case 'COMMENV_N6_3/4': {$pf = array( 260.640, 468.000); break;}
2423: case 'COMMENV_N8' : {$pf = array( 278.640, 540.000); break;}
2424: case 'COMMENV_N9' : {$pf = array( 278.640, 638.640); break;}
2425: case 'COMMENV_N10' : {$pf = array( 296.640, 684.000); break;}
2426: case 'COMMENV_N11' : {$pf = array( 324.000, 746.640); break;}
2427: case 'COMMENV_N12' : {$pf = array( 342.000, 792.000); break;}
2428: case 'COMMENV_N14' : {$pf = array( 360.000, 828.000); break;}
2429:
2430: case 'CATENV_N1' : {$pf = array( 432.000, 648.000); break;}
2431: case 'CATENV_N1_3/4' : {$pf = array( 468.000, 684.000); break;}
2432: case 'CATENV_N2' : {$pf = array( 468.000, 720.000); break;}
2433: case 'CATENV_N3' : {$pf = array( 504.000, 720.000); break;}
2434: case 'CATENV_N6' : {$pf = array( 540.000, 756.000); break;}
2435: case 'CATENV_N7' : {$pf = array( 576.000, 792.000); break;}
2436: case 'CATENV_N8' : {$pf = array( 594.000, 810.000); break;}
2437: case 'CATENV_N9_1/2' : {$pf = array( 612.000, 756.000); break;}
2438: case 'CATENV_N9_3/4' : {$pf = array( 630.000, 810.000); break;}
2439: case 'CATENV_N10_1/2': {$pf = array( 648.000, 864.000); break;}
2440: case 'CATENV_N12_1/2': {$pf = array( 684.000, 900.000); break;}
2441: case 'CATENV_N13_1/2': {$pf = array( 720.000, 936.000); break;}
2442: case 'CATENV_N14_1/4': {$pf = array( 810.000, 882.000); break;}
2443: case 'CATENV_N14_1/2': {$pf = array( 828.000, 1044.000); break;}
2444:
2445: case 'JIS_B0' : {$pf = array( 2919.685, 4127.244); break;}
2446: case 'JIS_B1' : {$pf = array( 2063.622, 2919.685); break;}
2447: case 'JIS_B2' : {$pf = array( 1459.843, 2063.622); break;}
2448: case 'JIS_B3' : {$pf = array( 1031.811, 1459.843); break;}
2449: case 'JIS_B4' : {$pf = array( 728.504, 1031.811); break;}
2450: case 'JIS_B5' : {$pf = array( 515.906, 728.504); break;}
2451: case 'JIS_B6' : {$pf = array( 362.835, 515.906); break;}
2452: case 'JIS_B7' : {$pf = array( 257.953, 362.835); break;}
2453: case 'JIS_B8' : {$pf = array( 181.417, 257.953); break;}
2454: case 'JIS_B9' : {$pf = array( 127.559, 181.417); break;}
2455: case 'JIS_B10': {$pf = array( 90.709, 127.559); break;}
2456: case 'JIS_B11': {$pf = array( 62.362, 90.709); break;}
2457: case 'JIS_B12': {$pf = array( 45.354, 62.362); break;}
2458:
2459: case 'PA0' : {$pf = array( 2381.102, 3174.803,); break;}
2460: case 'PA1' : {$pf = array( 1587.402, 2381.102); break;}
2461: case 'PA2' : {$pf = array( 1190.551, 1587.402); break;}
2462: case 'PA3' : {$pf = array( 793.701, 1190.551); break;}
2463: case 'PA4' : {$pf = array( 595.276, 793.701); break;}
2464: case 'PA5' : {$pf = array( 396.850, 595.276); break;}
2465: case 'PA6' : {$pf = array( 297.638, 396.850); break;}
2466: case 'PA7' : {$pf = array( 198.425, 297.638); break;}
2467: case 'PA8' : {$pf = array( 147.402, 198.425); break;}
2468: case 'PA9' : {$pf = array( 99.213, 147.402); break;}
2469: case 'PA10': {$pf = array( 73.701, 99.213); break;}
2470:
2471: case 'PASSPORT_PHOTO': {$pf = array( 99.213, 127.559); break;}
2472: case 'E' : {$pf = array( 233.858, 340.157); break;}
2473: case 'L':
2474: case '3R' : {$pf = array( 252.283, 360.000); break;}
2475: case 'KG':
2476: case '4R' : {$pf = array( 289.134, 430.866); break;}
2477: case '4D' : {$pf = array( 340.157, 430.866); break;}
2478: case '2L':
2479: case '5R' : {$pf = array( 360.000, 504.567); break;}
2480: case '8P':
2481: case '6R' : {$pf = array( 430.866, 575.433); break;}
2482: case '6P':
2483: case '8R' : {$pf = array( 575.433, 720.000); break;}
2484: case '6PW':
2485: case 'S8R' : {$pf = array( 575.433, 864.567); break;}
2486: case '4P':
2487: case '10R' : {$pf = array( 720.000, 864.567); break;}
2488: case '4PW':
2489: case 'S10R': {$pf = array( 720.000, 1080.000); break;}
2490: case '11R' : {$pf = array( 790.866, 1009.134); break;}
2491: case 'S11R': {$pf = array( 790.866, 1224.567); break;}
2492: case '12R' : {$pf = array( 864.567, 1080.000); break;}
2493: case 'S12R': {$pf = array( 864.567, 1292.598); break;}
2494:
2495: case 'NEWSPAPER_BROADSHEET': {$pf = array( 2125.984, 1700.787); break;}
2496: case 'NEWSPAPER_BERLINER' : {$pf = array( 1332.283, 892.913); break;}
2497: case 'NEWSPAPER_TABLOID':
2498: case 'NEWSPAPER_COMPACT' : {$pf = array( 1218.898, 793.701); break;}
2499:
2500: case 'CREDIT_CARD':
2501: case 'BUSINESS_CARD':
2502: case 'BUSINESS_CARD_ISO7810': {$pf = array( 153.014, 242.646); break;}
2503: case 'BUSINESS_CARD_ISO216' : {$pf = array( 147.402, 209.764); break;}
2504: case 'BUSINESS_CARD_IT':
2505: case 'BUSINESS_CARD_UK':
2506: case 'BUSINESS_CARD_FR':
2507: case 'BUSINESS_CARD_DE':
2508: case 'BUSINESS_CARD_ES' : {$pf = array( 155.906, 240.945); break;}
2509: case 'BUSINESS_CARD_CA':
2510: case 'BUSINESS_CARD_US' : {$pf = array( 144.567, 252.283); break;}
2511: case 'BUSINESS_CARD_JP' : {$pf = array( 155.906, 257.953); break;}
2512: case 'BUSINESS_CARD_HK' : {$pf = array( 153.071, 255.118); break;}
2513: case 'BUSINESS_CARD_AU':
2514: case 'BUSINESS_CARD_DK':
2515: case 'BUSINESS_CARD_SE' : {$pf = array( 155.906, 255.118); break;}
2516: case 'BUSINESS_CARD_RU':
2517: case 'BUSINESS_CARD_CZ':
2518: case 'BUSINESS_CARD_FI':
2519: case 'BUSINESS_CARD_HU':
2520: case 'BUSINESS_CARD_IL' : {$pf = array( 141.732, 255.118); break;}
2521:
2522: case '4SHEET' : {$pf = array( 2880.000, 4320.000); break;}
2523: case '6SHEET' : {$pf = array( 3401.575, 5102.362); break;}
2524: case '12SHEET': {$pf = array( 8640.000, 4320.000); break;}
2525: case '16SHEET': {$pf = array( 5760.000, 8640.000); break;}
2526: case '32SHEET': {$pf = array(11520.000, 8640.000); break;}
2527: case '48SHEET': {$pf = array(17280.000, 8640.000); break;}
2528: case '64SHEET': {$pf = array(23040.000, 8640.000); break;}
2529: case '96SHEET': {$pf = array(34560.000, 8640.000); break;}
2530:
2531:
2532: case 'EN_EMPEROR' : {$pf = array( 3456.000, 5184.000); break;}
2533: case 'EN_ANTIQUARIAN' : {$pf = array( 2232.000, 3816.000); break;}
2534: case 'EN_GRAND_EAGLE' : {$pf = array( 2070.000, 3024.000); break;}
2535: case 'EN_DOUBLE_ELEPHANT' : {$pf = array( 1926.000, 2880.000); break;}
2536: case 'EN_ATLAS' : {$pf = array( 1872.000, 2448.000); break;}
2537: case 'EN_COLOMBIER' : {$pf = array( 1692.000, 2484.000); break;}
2538: case 'EN_ELEPHANT' : {$pf = array( 1656.000, 2016.000); break;}
2539: case 'EN_DOUBLE_DEMY' : {$pf = array( 1620.000, 2556.000); break;}
2540: case 'EN_IMPERIAL' : {$pf = array( 1584.000, 2160.000); break;}
2541: case 'EN_PRINCESS' : {$pf = array( 1548.000, 2016.000); break;}
2542: case 'EN_CARTRIDGE' : {$pf = array( 1512.000, 1872.000); break;}
2543: case 'EN_DOUBLE_LARGE_POST': {$pf = array( 1512.000, 2376.000); break;}
2544: case 'EN_ROYAL' : {$pf = array( 1440.000, 1800.000); break;}
2545: case 'EN_SHEET':
2546: case 'EN_HALF_POST' : {$pf = array( 1404.000, 1692.000); break;}
2547: case 'EN_SUPER_ROYAL' : {$pf = array( 1368.000, 1944.000); break;}
2548: case 'EN_DOUBLE_POST' : {$pf = array( 1368.000, 2196.000); break;}
2549: case 'EN_MEDIUM' : {$pf = array( 1260.000, 1656.000); break;}
2550: case 'EN_DEMY' : {$pf = array( 1260.000, 1620.000); break;}
2551: case 'EN_LARGE_POST' : {$pf = array( 1188.000, 1512.000); break;}
2552: case 'EN_COPY_DRAUGHT' : {$pf = array( 1152.000, 1440.000); break;}
2553: case 'EN_POST' : {$pf = array( 1116.000, 1386.000); break;}
2554: case 'EN_CROWN' : {$pf = array( 1080.000, 1440.000); break;}
2555: case 'EN_PINCHED_POST' : {$pf = array( 1062.000, 1332.000); break;}
2556: case 'EN_BRIEF' : {$pf = array( 972.000, 1152.000); break;}
2557: case 'EN_FOOLSCAP' : {$pf = array( 972.000, 1224.000); break;}
2558: case 'EN_SMALL_FOOLSCAP' : {$pf = array( 954.000, 1188.000); break;}
2559: case 'EN_POTT' : {$pf = array( 900.000, 1080.000); break;}
2560:
2561: case 'BE_GRAND_AIGLE' : {$pf = array( 1984.252, 2948.031); break;}
2562: case 'BE_COLOMBIER' : {$pf = array( 1757.480, 2409.449); break;}
2563: case 'BE_DOUBLE_CARRE': {$pf = array( 1757.480, 2607.874); break;}
2564: case 'BE_ELEPHANT' : {$pf = array( 1746.142, 2182.677); break;}
2565: case 'BE_PETIT_AIGLE' : {$pf = array( 1700.787, 2381.102); break;}
2566: case 'BE_GRAND_JESUS' : {$pf = array( 1559.055, 2069.291); break;}
2567: case 'BE_JESUS' : {$pf = array( 1530.709, 2069.291); break;}
2568: case 'BE_RAISIN' : {$pf = array( 1417.323, 1842.520); break;}
2569: case 'BE_GRAND_MEDIAN': {$pf = array( 1303.937, 1714.961); break;}
2570: case 'BE_DOUBLE_POSTE': {$pf = array( 1233.071, 1601.575); break;}
2571: case 'BE_COQUILLE' : {$pf = array( 1218.898, 1587.402); break;}
2572: case 'BE_PETIT_MEDIAN': {$pf = array( 1176.378, 1502.362); break;}
2573: case 'BE_RUCHE' : {$pf = array( 1020.472, 1303.937); break;}
2574: case 'BE_PROPATRIA' : {$pf = array( 977.953, 1218.898); break;}
2575: case 'BE_LYS' : {$pf = array( 898.583, 1125.354); break;}
2576: case 'BE_POT' : {$pf = array( 870.236, 1088.504); break;}
2577: case 'BE_ROSETTE' : {$pf = array( 765.354, 983.622); break;}
2578:
2579: case 'FR_UNIVERS' : {$pf = array( 2834.646, 3685.039); break;}
2580: case 'FR_DOUBLE_COLOMBIER' : {$pf = array( 2551.181, 3571.654); break;}
2581: case 'FR_GRANDE_MONDE' : {$pf = array( 2551.181, 3571.654); break;}
2582: case 'FR_DOUBLE_SOLEIL' : {$pf = array( 2267.717, 3401.575); break;}
2583: case 'FR_DOUBLE_JESUS' : {$pf = array( 2154.331, 3174.803); break;}
2584: case 'FR_GRAND_AIGLE' : {$pf = array( 2125.984, 3004.724); break;}
2585: case 'FR_PETIT_AIGLE' : {$pf = array( 1984.252, 2664.567); break;}
2586: case 'FR_DOUBLE_RAISIN' : {$pf = array( 1842.520, 2834.646); break;}
2587: case 'FR_JOURNAL' : {$pf = array( 1842.520, 2664.567); break;}
2588: case 'FR_COLOMBIER_AFFICHE': {$pf = array( 1785.827, 2551.181); break;}
2589: case 'FR_DOUBLE_CAVALIER' : {$pf = array( 1757.480, 2607.874); break;}
2590: case 'FR_CLOCHE' : {$pf = array( 1700.787, 2267.717); break;}
2591: case 'FR_SOLEIL' : {$pf = array( 1700.787, 2267.717); break;}
2592: case 'FR_DOUBLE_CARRE' : {$pf = array( 1587.402, 2551.181); break;}
2593: case 'FR_DOUBLE_COQUILLE' : {$pf = array( 1587.402, 2494.488); break;}
2594: case 'FR_JESUS' : {$pf = array( 1587.402, 2154.331); break;}
2595: case 'FR_RAISIN' : {$pf = array( 1417.323, 1842.520); break;}
2596: case 'FR_CAVALIER' : {$pf = array( 1303.937, 1757.480); break;}
2597: case 'FR_DOUBLE_COURONNE' : {$pf = array( 1303.937, 2040.945); break;}
2598: case 'FR_CARRE' : {$pf = array( 1275.591, 1587.402); break;}
2599: case 'FR_COQUILLE' : {$pf = array( 1247.244, 1587.402); break;}
2600: case 'FR_DOUBLE_TELLIERE' : {$pf = array( 1247.244, 1927.559); break;}
2601: case 'FR_DOUBLE_CLOCHE' : {$pf = array( 1133.858, 1700.787); break;}
2602: case 'FR_DOUBLE_POT' : {$pf = array( 1133.858, 1757.480); break;}
2603: case 'FR_ECU' : {$pf = array( 1133.858, 1474.016); break;}
2604: case 'FR_COURONNE' : {$pf = array( 1020.472, 1303.937); break;}
2605: case 'FR_TELLIERE' : {$pf = array( 963.780, 1247.244); break;}
2606: case 'FR_POT' : {$pf = array( 878.740, 1133.858); break;}
2607:
2608: default: {$pf = array( 595.276, 841.890); break;}
2609: }
2610: return $pf;
2611: }
2612:
2613: 2614: 2615: 2616: 2617: 2618: 2619: 2620: 2621: 2622: 2623: 2624: 2625: 2626: 2627: 2628: 2629: 2630: 2631: 2632: 2633: 2634: 2635: 2636: 2637: 2638: 2639: 2640: 2641: 2642: 2643: 2644: 2645: 2646: 2647: 2648: 2649: 2650: 2651: 2652: 2653: 2654: 2655: 2656: 2657: 2658: 2659: 2660: 2661: 2662: 2663: 2664: 2665: 2666: 2667:
2668: protected function setPageFormat($format, $orientation='P') {
2669: if (!empty($format) AND isset($this->pagedim[$this->page])) {
2670:
2671: unset($this->pagedim[$this->page]);
2672: }
2673: if (is_string($format)) {
2674:
2675: $pf = $this->getPageSizeFromFormat($format);
2676: $this->fwPt = $pf[0];
2677: $this->fhPt = $pf[1];
2678: } else {
2679:
2680: if (isset($format['MediaBox'])) {
2681: $this->setPageBoxes($this->page, 'MediaBox', $format['MediaBox']['llx'], $format['MediaBox']['lly'], $format['MediaBox']['urx'], $format['MediaBox']['ury'], false);
2682: $this->fwPt = (($format['MediaBox']['urx'] - $format['MediaBox']['llx']) * $this->k);
2683: $this->fhPt = (($format['MediaBox']['ury'] - $format['MediaBox']['lly']) * $this->k);
2684: } else {
2685: if (isset($format[0]) AND is_numeric($format[0]) AND isset($format[1]) AND is_numeric($format[1])) {
2686: $pf = array(($format[0] * $this->k), ($format[1] * $this->k));
2687: } else {
2688: if (!isset($format['format'])) {
2689:
2690: $format['format'] = 'A4';
2691: }
2692: $pf = $this->getPageSizeFromFormat($format['format']);
2693: }
2694: $this->fwPt = $pf[0];
2695: $this->fhPt = $pf[1];
2696: $this->setPageBoxes($this->page, 'MediaBox', 0, 0, $this->fwPt, $this->fhPt, true);
2697: }
2698:
2699: if (isset($format['CropBox'])) {
2700: $this->setPageBoxes($this->page, 'CropBox', $format['CropBox']['llx'], $format['CropBox']['lly'], $format['CropBox']['urx'], $format['CropBox']['ury'], false);
2701: }
2702:
2703: if (isset($format['BleedBox'])) {
2704: $this->setPageBoxes($this->page, 'BleedBox', $format['BleedBox']['llx'], $format['BleedBox']['lly'], $format['BleedBox']['urx'], $format['BleedBox']['ury'], false);
2705: }
2706:
2707: if (isset($format['TrimBox'])) {
2708: $this->setPageBoxes($this->page, 'TrimBox', $format['TrimBox']['llx'], $format['TrimBox']['lly'], $format['TrimBox']['urx'], $format['TrimBox']['ury'], false);
2709: }
2710:
2711: if (isset($format['ArtBox'])) {
2712: $this->setPageBoxes($this->page, 'ArtBox', $format['ArtBox']['llx'], $format['ArtBox']['lly'], $format['ArtBox']['urx'], $format['ArtBox']['ury'], false);
2713: }
2714:
2715: if (isset($format['BoxColorInfo'])) {
2716: $this->pagedim[$this->page]['BoxColorInfo'] = $format['BoxColorInfo'];
2717: }
2718: if (isset($format['Rotate']) AND (($format['Rotate'] % 90) == 0)) {
2719:
2720: $this->pagedim[$this->page]['Rotate'] = intval($format['Rotate']);
2721: }
2722: if (isset($format['PZ'])) {
2723:
2724: $this->pagedim[$this->page]['PZ'] = floatval($format['PZ']);
2725: }
2726: if (isset($format['trans'])) {
2727:
2728: if (isset($format['trans']['Dur'])) {
2729:
2730: $this->pagedim[$this->page]['trans']['Dur'] = floatval($format['trans']['Dur']);
2731: }
2732: $stansition_styles = array('Split', 'Blinds', 'Box', 'Wipe', 'Dissolve', 'Glitter', 'R', 'Fly', 'Push', 'Cover', 'Uncover', 'Fade');
2733: if (isset($format['trans']['S']) AND in_array($format['trans']['S'], $stansition_styles)) {
2734:
2735: $this->pagedim[$this->page]['trans']['S'] = $format['trans']['S'];
2736: $valid_effect = array('Split', 'Blinds');
2737: $valid_vals = array('H', 'V');
2738: if (isset($format['trans']['Dm']) AND in_array($format['trans']['S'], $valid_effect) AND in_array($format['trans']['Dm'], $valid_vals)) {
2739: $this->pagedim[$this->page]['trans']['Dm'] = $format['trans']['Dm'];
2740: }
2741: $valid_effect = array('Split', 'Box', 'Fly');
2742: $valid_vals = array('I', 'O');
2743: if (isset($format['trans']['M']) AND in_array($format['trans']['S'], $valid_effect) AND in_array($format['trans']['M'], $valid_vals)) {
2744: $this->pagedim[$this->page]['trans']['M'] = $format['trans']['M'];
2745: }
2746: $valid_effect = array('Wipe', 'Glitter', 'Fly', 'Cover', 'Uncover', 'Push');
2747: if (isset($format['trans']['Di']) AND in_array($format['trans']['S'], $valid_effect)) {
2748: if (((($format['trans']['Di'] == 90) OR ($format['trans']['Di'] == 180)) AND ($format['trans']['S'] == 'Wipe'))
2749: OR (($format['trans']['Di'] == 315) AND ($format['trans']['S'] == 'Glitter'))
2750: OR (($format['trans']['Di'] == 0) OR ($format['trans']['Di'] == 270))) {
2751: $this->pagedim[$this->page]['trans']['Di'] = intval($format['trans']['Di']);
2752: }
2753: }
2754: if (isset($format['trans']['SS']) AND ($format['trans']['S'] == 'Fly')) {
2755: $this->pagedim[$this->page]['trans']['SS'] = floatval($format['trans']['SS']);
2756: }
2757: if (isset($format['trans']['B']) AND ($format['trans']['B'] === true) AND ($format['trans']['S'] == 'Fly')) {
2758: $this->pagedim[$this->page]['trans']['B'] = 'true';
2759: }
2760: } else {
2761: $this->pagedim[$this->page]['trans']['S'] = 'R';
2762: }
2763: if (isset($format['trans']['D'])) {
2764:
2765: $this->pagedim[$this->page]['trans']['D'] = floatval($format['trans']['D']);
2766: } else {
2767: $this->pagedim[$this->page]['trans']['D'] = 1;
2768: }
2769: }
2770: }
2771: $this->setPageOrientation($orientation);
2772: }
2773:
2774: 2775: 2776: 2777: 2778: 2779: 2780: 2781: 2782: 2783: 2784: 2785:
2786: public function setPageBoxes($page, $type, $llx, $lly, $urx, $ury, $points=false) {
2787: if (!isset($this->pagedim[$page])) {
2788:
2789: $this->pagedim[$page] = array();
2790: }
2791: $pageboxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
2792: if (!in_array($type, $pageboxes)) {
2793: return;
2794: }
2795: if ($points) {
2796: $k = 1;
2797: } else {
2798: $k = $this->k;
2799: }
2800: $this->pagedim[$page][$type]['llx'] = ($llx * $k);
2801: $this->pagedim[$page][$type]['lly'] = ($lly * $k);
2802: $this->pagedim[$page][$type]['urx'] = ($urx * $k);
2803: $this->pagedim[$page][$type]['ury'] = ($ury * $k);
2804: }
2805:
2806: 2807: 2808: 2809: 2810: 2811:
2812: protected function swapPageBoxCoordinates($page) {
2813: $pageboxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
2814: foreach ($pageboxes as $type) {
2815:
2816: if (isset($this->pagedim[$page][$type])) {
2817: $tmp = $this->pagedim[$page][$type]['llx'];
2818: $this->pagedim[$page][$type]['llx'] = $this->pagedim[$page][$type]['lly'];
2819: $this->pagedim[$page][$type]['lly'] = $tmp;
2820: $tmp = $this->pagedim[$page][$type]['urx'];
2821: $this->pagedim[$page][$type]['urx'] = $this->pagedim[$page][$type]['ury'];
2822: $this->pagedim[$page][$type]['ury'] = $tmp;
2823: }
2824: }
2825: }
2826:
2827: 2828: 2829: 2830: 2831: 2832: 2833: 2834:
2835: public function setPageOrientation($orientation, $autopagebreak='', $bottommargin='') {
2836: if (!isset($this->pagedim[$this->page]['MediaBox'])) {
2837:
2838: $this->setPageBoxes($this->page, 'MediaBox', 0, 0, $this->fwPt, $this->fhPt, true);
2839: }
2840: if (!isset($this->pagedim[$this->page]['CropBox'])) {
2841:
2842: $this->setPageBoxes($this->page, 'CropBox', $this->pagedim[$this->page]['MediaBox']['llx'], $this->pagedim[$this->page]['MediaBox']['lly'], $this->pagedim[$this->page]['MediaBox']['urx'], $this->pagedim[$this->page]['MediaBox']['ury'], true);
2843: }
2844: if (!isset($this->pagedim[$this->page]['BleedBox'])) {
2845:
2846: $this->setPageBoxes($this->page, 'BleedBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true);
2847: }
2848: if (!isset($this->pagedim[$this->page]['TrimBox'])) {
2849:
2850: $this->setPageBoxes($this->page, 'TrimBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true);
2851: }
2852: if (!isset($this->pagedim[$this->page]['ArtBox'])) {
2853:
2854: $this->setPageBoxes($this->page, 'ArtBox', $this->pagedim[$this->page]['CropBox']['llx'], $this->pagedim[$this->page]['CropBox']['lly'], $this->pagedim[$this->page]['CropBox']['urx'], $this->pagedim[$this->page]['CropBox']['ury'], true);
2855: }
2856: if (!isset($this->pagedim[$this->page]['Rotate'])) {
2857:
2858: $this->pagedim[$this->page]['Rotate'] = 0;
2859: }
2860: if (!isset($this->pagedim[$this->page]['PZ'])) {
2861:
2862: $this->pagedim[$this->page]['PZ'] = 1;
2863: }
2864: if ($this->fwPt > $this->fhPt) {
2865:
2866: $default_orientation = 'L';
2867: } else {
2868:
2869: $default_orientation = 'P';
2870: }
2871: $valid_orientations = array('P', 'L');
2872: if (empty($orientation)) {
2873: $orientation = $default_orientation;
2874: } else {
2875: $orientation = strtoupper($orientation{0});
2876: }
2877: if (in_array($orientation, $valid_orientations) AND ($orientation != $default_orientation)) {
2878: $this->CurOrientation = $orientation;
2879: $this->wPt = $this->fhPt;
2880: $this->hPt = $this->fwPt;
2881: } else {
2882: $this->CurOrientation = $default_orientation;
2883: $this->wPt = $this->fwPt;
2884: $this->hPt = $this->fhPt;
2885: }
2886: if ((abs($this->pagedim[$this->page]['MediaBox']['urx'] - $this->hPt) < $this->feps) AND (abs($this->pagedim[$this->page]['MediaBox']['ury'] - $this->wPt) < $this->feps)){
2887:
2888: $this->swapPageBoxCoordinates($this->page);
2889: }
2890: $this->w = $this->wPt / $this->k;
2891: $this->h = $this->hPt / $this->k;
2892: if ($this->empty_string($autopagebreak)) {
2893: if (isset($this->AutoPageBreak)) {
2894: $autopagebreak = $this->AutoPageBreak;
2895: } else {
2896: $autopagebreak = true;
2897: }
2898: }
2899: if ($this->empty_string($bottommargin)) {
2900: if (isset($this->bMargin)) {
2901: $bottommargin = $this->bMargin;
2902: } else {
2903:
2904: $bottommargin = 2 * 28.35 / $this->k;
2905: }
2906: }
2907: $this->SetAutoPageBreak($autopagebreak, $bottommargin);
2908:
2909: $this->pagedim[$this->page]['w'] = $this->wPt;
2910: $this->pagedim[$this->page]['h'] = $this->hPt;
2911: $this->pagedim[$this->page]['wk'] = $this->w;
2912: $this->pagedim[$this->page]['hk'] = $this->h;
2913: $this->pagedim[$this->page]['tm'] = $this->tMargin;
2914: $this->pagedim[$this->page]['bm'] = $bottommargin;
2915: $this->pagedim[$this->page]['lm'] = $this->lMargin;
2916: $this->pagedim[$this->page]['rm'] = $this->rMargin;
2917: $this->pagedim[$this->page]['pb'] = $autopagebreak;
2918: $this->pagedim[$this->page]['or'] = $this->CurOrientation;
2919: $this->pagedim[$this->page]['olm'] = $this->original_lMargin;
2920: $this->pagedim[$this->page]['orm'] = $this->original_rMargin;
2921: }
2922:
2923: 2924: 2925: 2926: 2927: 2928: 2929: 2930: 2931: 2932: 2933: 2934: 2935: 2936: 2937: 2938: 2939:
2940: public function setSpacesRE($re='/[^\S\xa0]/') {
2941: $this->re_spaces = $re;
2942: $re_parts = explode('/', $re);
2943:
2944: $this->re_space = array();
2945: if (isset($re_parts[1]) AND !empty($re_parts[1])) {
2946: $this->re_space['p'] = $re_parts[1];
2947: } else {
2948: $this->re_space['p'] = '[\s]';
2949: }
2950:
2951: if (isset($re_parts[2]) AND !empty($re_parts[2])) {
2952: $this->re_space['m'] = $re_parts[2];
2953: } else {
2954: $this->re_space['m'] = '';
2955: }
2956: }
2957:
2958: 2959: 2960: 2961: 2962: 2963: 2964:
2965: public function setRTL($enable, $resetx=true) {
2966: $enable = $enable ? true : false;
2967: $resetx = ($resetx AND ($enable != $this->rtl));
2968: $this->rtl = $enable;
2969: $this->tmprtl = false;
2970: if ($resetx) {
2971: $this->Ln(0);
2972: }
2973: }
2974:
2975: 2976: 2977: 2978: 2979: 2980:
2981: public function getRTL() {
2982: return $this->rtl;
2983: }
2984:
2985: 2986: 2987: 2988: 2989: 2990:
2991: public function setTempRTL($mode) {
2992: $newmode = false;
2993: switch (strtoupper($mode)) {
2994: case 'LTR':
2995: case 'L': {
2996: if ($this->rtl) {
2997: $newmode = 'L';
2998: }
2999: break;
3000: }
3001: case 'RTL':
3002: case 'R': {
3003: if (!$this->rtl) {
3004: $newmode = 'R';
3005: }
3006: break;
3007: }
3008: case false:
3009: default: {
3010: $newmode = false;
3011: break;
3012: }
3013: }
3014: $this->tmprtl = $newmode;
3015: }
3016:
3017: 3018: 3019: 3020: 3021: 3022:
3023: public function isRTLTextDir() {
3024: return ($this->rtl OR ($this->tmprtl == 'R'));
3025: }
3026:
3027: 3028: 3029: 3030: 3031: 3032: 3033:
3034: public function setLastH($h) {
3035: $this->lasth = $h;
3036: }
3037:
3038: 3039: 3040: 3041: 3042:
3043: public function resetLastH() {
3044: $this->lasth = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B'];
3045: }
3046:
3047: 3048: 3049: 3050: 3051: 3052:
3053: public function getLastH() {
3054: return $this->lasth;
3055: }
3056:
3057: 3058: 3059: 3060: 3061: 3062: 3063:
3064: public function setImageScale($scale) {
3065: $this->imgscale = $scale;
3066: }
3067:
3068: 3069: 3070: 3071: 3072: 3073: 3074:
3075: public function getImageScale() {
3076: return $this->imgscale;
3077: }
3078:
3079: 3080: 3081: 3082: 3083: 3084: 3085: 3086: 3087:
3088: public function getPageDimensions($pagenum='') {
3089: if (empty($pagenum)) {
3090: $pagenum = $this->page;
3091: }
3092: return $this->pagedim[$pagenum];
3093: }
3094:
3095: 3096: 3097: 3098: 3099: 3100: 3101: 3102: 3103:
3104: public function getPageWidth($pagenum='') {
3105: if (empty($pagenum)) {
3106: return $this->w;
3107: }
3108: return $this->pagedim[$pagenum]['w'];
3109: }
3110:
3111: 3112: 3113: 3114: 3115: 3116: 3117: 3118: 3119:
3120: public function getPageHeight($pagenum='') {
3121: if (empty($pagenum)) {
3122: return $this->h;
3123: }
3124: return $this->pagedim[$pagenum]['h'];
3125: }
3126:
3127: 3128: 3129: 3130: 3131: 3132: 3133: 3134: 3135:
3136: public function getBreakMargin($pagenum='') {
3137: if (empty($pagenum)) {
3138: return $this->bMargin;
3139: }
3140: return $this->pagedim[$pagenum]['bm'];
3141: }
3142:
3143: 3144: 3145: 3146: 3147: 3148: 3149:
3150: public function getScaleFactor() {
3151: return $this->k;
3152: }
3153:
3154: 3155: 3156: 3157: 3158: 3159: 3160: 3161: 3162: 3163:
3164: public function SetMargins($left, $top, $right=-1, $keepmargins=false) {
3165:
3166: $this->lMargin = $left;
3167: $this->tMargin = $top;
3168: if ($right == -1) {
3169: $right = $left;
3170: }
3171: $this->rMargin = $right;
3172: if ($keepmargins) {
3173:
3174: $this->original_lMargin = $this->lMargin;
3175: $this->original_rMargin = $this->rMargin;
3176: }
3177: }
3178:
3179: 3180: 3181: 3182: 3183: 3184: 3185:
3186: public function SetLeftMargin($margin) {
3187:
3188: $this->lMargin = $margin;
3189: if (($this->page > 0) AND ($this->x < $margin)) {
3190: $this->x = $margin;
3191: }
3192: }
3193:
3194: 3195: 3196: 3197: 3198: 3199: 3200:
3201: public function SetTopMargin($margin) {
3202:
3203: $this->tMargin = $margin;
3204: if (($this->page > 0) AND ($this->y < $margin)) {
3205: $this->y = $margin;
3206: }
3207: }
3208:
3209: 3210: 3211: 3212: 3213: 3214: 3215:
3216: public function SetRightMargin($margin) {
3217: $this->rMargin = $margin;
3218: if (($this->page > 0) AND ($this->x > ($this->w - $margin))) {
3219: $this->x = $this->w - $margin;
3220: }
3221: }
3222:
3223: 3224: 3225: 3226: 3227: 3228: 3229:
3230: public function SetCellPadding($pad) {
3231: if ($pad >= 0) {
3232: $this->cell_padding['L'] = $pad;
3233: $this->cell_padding['T'] = $pad;
3234: $this->cell_padding['R'] = $pad;
3235: $this->cell_padding['B'] = $pad;
3236: }
3237: }
3238:
3239: 3240: 3241: 3242: 3243: 3244: 3245: 3246: 3247: 3248:
3249: public function setCellPaddings($left='', $top='', $right='', $bottom='') {
3250: if (($left !== '') AND ($left >= 0)) {
3251: $this->cell_padding['L'] = $left;
3252: }
3253: if (($top !== '') AND ($top >= 0)) {
3254: $this->cell_padding['T'] = $top;
3255: }
3256: if (($right !== '') AND ($right >= 0)) {
3257: $this->cell_padding['R'] = $right;
3258: }
3259: if (($bottom !== '') AND ($bottom >= 0)) {
3260: $this->cell_padding['B'] = $bottom;
3261: }
3262: }
3263:
3264: 3265: 3266: 3267: 3268: 3269: 3270:
3271: public function getCellPaddings() {
3272: return $this->cell_padding;
3273: }
3274:
3275: 3276: 3277: 3278: 3279: 3280: 3281: 3282: 3283: 3284:
3285: public function setCellMargins($left='', $top='', $right='', $bottom='') {
3286: if (($left !== '') AND ($left >= 0)) {
3287: $this->cell_margin['L'] = $left;
3288: }
3289: if (($top !== '') AND ($top >= 0)) {
3290: $this->cell_margin['T'] = $top;
3291: }
3292: if (($right !== '') AND ($right >= 0)) {
3293: $this->cell_margin['R'] = $right;
3294: }
3295: if (($bottom !== '') AND ($bottom >= 0)) {
3296: $this->cell_margin['B'] = $bottom;
3297: }
3298: }
3299:
3300: 3301: 3302: 3303: 3304: 3305: 3306:
3307: public function getCellMargins() {
3308: return $this->cell_margin;
3309: }
3310:
3311: 3312: 3313: 3314: 3315: 3316: 3317:
3318: protected function adjustCellPadding($brd=0) {
3319: if (empty($brd)) {
3320: return;
3321: }
3322: if (is_string($brd)) {
3323:
3324: $slen = strlen($brd);
3325: $newbrd = array();
3326: for ($i = 0; $i < $slen; ++$i) {
3327: $newbrd[$brd{$i}] = true;
3328: }
3329: $brd = $newbrd;
3330: } elseif (($brd === 1) OR ($brd === true) OR (is_numeric($brd) AND (intval($brd) > 0))) {
3331: $brd = array('LRTB' => true);
3332: }
3333: if (!is_array($brd)) {
3334: return;
3335: }
3336:
3337: $cp = $this->cell_padding;
3338:
3339: if (isset($brd['mode'])) {
3340: $mode = $brd['mode'];
3341: unset($brd['mode']);
3342: } else {
3343: $mode = 'normal';
3344: }
3345:
3346: foreach ($brd as $border => $style) {
3347: $line_width = $this->LineWidth;
3348: if (is_array($style) AND isset($style['width'])) {
3349:
3350: $line_width = $style['width'];
3351: }
3352: $adj = 0;
3353: switch ($mode) {
3354: case 'ext': {
3355: $adj = 0;
3356: break;
3357: }
3358: case 'int': {
3359: $adj = $line_width;
3360: break;
3361: }
3362: case 'normal':
3363: default: {
3364: $adj = ($line_width / 2);
3365: break;
3366: }
3367: }
3368:
3369: if ((strpos($border,'T') !== false) AND ($this->cell_padding['T'] < $adj)) {
3370: $this->cell_padding['T'] = $adj;
3371: }
3372: if ((strpos($border,'R') !== false) AND ($this->cell_padding['R'] < $adj)) {
3373: $this->cell_padding['R'] = $adj;
3374: }
3375: if ((strpos($border,'B') !== false) AND ($this->cell_padding['B'] < $adj)) {
3376: $this->cell_padding['B'] = $adj;
3377: }
3378: if ((strpos($border,'L') !== false) AND ($this->cell_padding['L'] < $adj)) {
3379: $this->cell_padding['L'] = $adj;
3380: }
3381: }
3382: return array('T' => ($this->cell_padding['T'] - $cp['T']), 'R' => ($this->cell_padding['R'] - $cp['R']), 'B' => ($this->cell_padding['B'] - $cp['B']), 'L' => ($this->cell_padding['L'] - $cp['L']));
3383: }
3384:
3385: 3386: 3387: 3388: 3389: 3390: 3391: 3392:
3393: public function SetAutoPageBreak($auto, $margin=0) {
3394:
3395: $this->AutoPageBreak = $auto;
3396: $this->bMargin = $margin;
3397: $this->PageBreakTrigger = $this->h - $margin;
3398: }
3399:
3400: 3401: 3402: 3403: 3404: 3405: 3406: 3407:
3408: public function SetDisplayMode($zoom, $layout='SinglePage', $mode='UseNone') {
3409:
3410: if (($zoom == 'fullpage') OR ($zoom == 'fullwidth') OR ($zoom == 'real') OR ($zoom == 'default') OR (!is_string($zoom))) {
3411: $this->ZoomMode = $zoom;
3412: } else {
3413: $this->Error('Incorrect zoom display mode: '.$zoom);
3414: }
3415: switch ($layout) {
3416: case 'default':
3417: case 'single':
3418: case 'SinglePage': {
3419: $this->LayoutMode = 'SinglePage';
3420: break;
3421: }
3422: case 'continuous':
3423: case 'OneColumn': {
3424: $this->LayoutMode = 'OneColumn';
3425: break;
3426: }
3427: case 'two':
3428: case 'TwoColumnLeft': {
3429: $this->LayoutMode = 'TwoColumnLeft';
3430: break;
3431: }
3432: case 'TwoColumnRight': {
3433: $this->LayoutMode = 'TwoColumnRight';
3434: break;
3435: }
3436: case 'TwoPageLeft': {
3437: $this->LayoutMode = 'TwoPageLeft';
3438: break;
3439: }
3440: case 'TwoPageRight': {
3441: $this->LayoutMode = 'TwoPageRight';
3442: break;
3443: }
3444: default: {
3445: $this->LayoutMode = 'SinglePage';
3446: }
3447: }
3448: switch ($mode) {
3449: case 'UseNone': {
3450: $this->PageMode = 'UseNone';
3451: break;
3452: }
3453: case 'UseOutlines': {
3454: $this->PageMode = 'UseOutlines';
3455: break;
3456: }
3457: case 'UseThumbs': {
3458: $this->PageMode = 'UseThumbs';
3459: break;
3460: }
3461: case 'FullScreen': {
3462: $this->PageMode = 'FullScreen';
3463: break;
3464: }
3465: case 'UseOC': {
3466: $this->PageMode = 'UseOC';
3467: break;
3468: }
3469: case '': {
3470: $this->PageMode = 'UseAttachments';
3471: break;
3472: }
3473: default: {
3474: $this->PageMode = 'UseNone';
3475: }
3476: }
3477: }
3478:
3479: 3480: 3481: 3482: 3483: 3484: 3485:
3486: public function SetCompression($compress) {
3487:
3488: if (function_exists('gzcompress')) {
3489: $this->compress = $compress ? true : false;
3490: } else {
3491: $this->compress = false;
3492: }
3493: }
3494:
3495: 3496: 3497: 3498: 3499: 3500: 3501:
3502: public function SetTitle($title) {
3503:
3504: $this->title = $title;
3505: }
3506:
3507: 3508: 3509: 3510: 3511: 3512: 3513:
3514: public function SetSubject($subject) {
3515:
3516: $this->subject = $subject;
3517: }
3518:
3519: 3520: 3521: 3522: 3523: 3524: 3525:
3526: public function SetAuthor($author) {
3527:
3528: $this->author = $author;
3529: }
3530:
3531: 3532: 3533: 3534: 3535: 3536: 3537:
3538: public function SetKeywords($keywords) {
3539:
3540: $this->keywords = $keywords;
3541: }
3542:
3543: 3544: 3545: 3546: 3547: 3548: 3549:
3550: public function SetCreator($creator) {
3551:
3552: $this->creator = $creator;
3553: }
3554:
3555: 3556: 3557: 3558: 3559: 3560: 3561:
3562: public function Error($msg) {
3563:
3564: $this->_destroy(true);
3565:
3566: die('<strong>TCPDF ERROR: </strong>'.$msg);
3567: }
3568:
3569: 3570: 3571: 3572: 3573: 3574: 3575: 3576:
3577: public function Open() {
3578:
3579: $this->state = 1;
3580: }
3581:
3582: 3583: 3584: 3585: 3586: 3587: 3588: 3589:
3590: public function Close() {
3591: if ($this->state == 3) {
3592: return;
3593: }
3594: if ($this->page == 0) {
3595: $this->AddPage();
3596: }
3597:
3598: $gvars = $this->getGraphicVars();
3599: $this->lastpage(true);
3600: $this->SetAutoPageBreak(false);
3601: $this->x = 0;
3602: $this->y = $this->h - (1 / $this->k);
3603: $this->lMargin = 0;
3604: $this->_out('q');
3605: $this->setVisibility('screen');
3606: $this->SetFont('helvetica', '', 1);
3607: $this->SetTextColor(255, 255, 255);
3608: $msg = "\x50\x6f\x77\x65\x72\x65\x64\x20\x62\x79\x20\x54\x43\x50\x44\x46\x20\x28\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29";
3609: $lnk = "\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67";
3610: $this->Cell(0, 0, $msg, 0, 0, 'L', 0, $lnk, 0, false, 'D', 'B');
3611: $this->setVisibility('all');
3612: $this->_out('Q');
3613:
3614: $this->setGraphicVars($gvars);
3615:
3616: $this->endPage();
3617:
3618: $this->_enddoc();
3619:
3620: $this->_destroy(false);
3621: }
3622:
3623: 3624: 3625: 3626: 3627: 3628: 3629: 3630:
3631: public function setPage($pnum, $resetmargins=false) {
3632: if (($pnum == $this->page) AND ($this->state == 2)) {
3633: return;
3634: }
3635: if (($pnum > 0) AND ($pnum <= $this->numpages)) {
3636: $this->state = 2;
3637:
3638:
3639: $oldpage = $this->page;
3640: $this->page = $pnum;
3641: $this->wPt = $this->pagedim[$this->page]['w'];
3642: $this->hPt = $this->pagedim[$this->page]['h'];
3643: $this->w = $this->pagedim[$this->page]['wk'];
3644: $this->h = $this->pagedim[$this->page]['hk'];
3645: $this->tMargin = $this->pagedim[$this->page]['tm'];
3646: $this->bMargin = $this->pagedim[$this->page]['bm'];
3647: $this->original_lMargin = $this->pagedim[$this->page]['olm'];
3648: $this->original_rMargin = $this->pagedim[$this->page]['orm'];
3649: $this->AutoPageBreak = $this->pagedim[$this->page]['pb'];
3650: $this->CurOrientation = $this->pagedim[$this->page]['or'];
3651: $this->SetAutoPageBreak($this->AutoPageBreak, $this->bMargin);
3652:
3653:
3654: if ($resetmargins) {
3655: $this->lMargin = $this->pagedim[$this->page]['olm'];
3656: $this->rMargin = $this->pagedim[$this->page]['orm'];
3657: $this->SetY($this->tMargin);
3658: } else {
3659:
3660: if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) {
3661: $deltam = $this->pagedim[$this->page]['olm'] - $this->pagedim[$this->page]['orm'];
3662: $this->lMargin += $deltam;
3663: $this->rMargin -= $deltam;
3664: }
3665: }
3666: } else {
3667: $this->Error('Wrong page number on setPage() function: '.$pnum);
3668: }
3669: }
3670:
3671: 3672: 3673: 3674: 3675: 3676: 3677:
3678: public function lastPage($resetmargins=false) {
3679: $this->setPage($this->getNumPages(), $resetmargins);
3680: }
3681:
3682: 3683: 3684: 3685: 3686: 3687: 3688:
3689: public function getPage() {
3690: return $this->page;
3691: }
3692:
3693: 3694: 3695: 3696: 3697: 3698: 3699:
3700: public function getNumPages() {
3701: return $this->numpages;
3702: }
3703:
3704: 3705: 3706: 3707: 3708: 3709: 3710: 3711:
3712: public function addTOCPage($orientation='', $format='', $keepmargins=false) {
3713: $this->AddPage($orientation, $format, $keepmargins, true);
3714: }
3715:
3716: 3717: 3718: 3719: 3720: 3721:
3722: public function endTOCPage() {
3723: $this->endPage(true);
3724: }
3725:
3726: 3727: 3728: 3729: 3730: 3731: 3732: 3733: 3734: 3735: 3736:
3737: public function AddPage($orientation='', $format='', $keepmargins=false, $tocpage=false) {
3738: if ($this->inxobj) {
3739:
3740: return;
3741: }
3742: if (!isset($this->original_lMargin) OR $keepmargins) {
3743: $this->original_lMargin = $this->lMargin;
3744: }
3745: if (!isset($this->original_rMargin) OR $keepmargins) {
3746: $this->original_rMargin = $this->rMargin;
3747: }
3748:
3749: $this->endPage();
3750:
3751: $this->startPage($orientation, $format, $tocpage);
3752: }
3753:
3754: 3755: 3756: 3757: 3758: 3759: 3760:
3761: public function endPage($tocpage=false) {
3762:
3763: if (($this->page == 0) OR ($this->numpages > $this->page) OR (!$this->pageopen[$this->page])) {
3764: return;
3765: }
3766: $this->InFooter = true;
3767:
3768: $this->setFooter();
3769:
3770: $this->_endpage();
3771:
3772: $this->pageopen[$this->page] = false;
3773: $this->InFooter = false;
3774: if ($tocpage) {
3775: $this->tocpage = false;
3776: }
3777: }
3778:
3779: 3780: 3781: 3782: 3783: 3784: 3785: 3786: 3787:
3788: public function startPage($orientation='', $format='', $tocpage=false) {
3789: if ($tocpage) {
3790: $this->tocpage = true;
3791: }
3792: if ($this->numpages > $this->page) {
3793:
3794: $this->setPage($this->page + 1);
3795: $this->SetY($this->tMargin);
3796: return;
3797: }
3798:
3799: if ($this->state == 0) {
3800: $this->Open();
3801: }
3802: ++$this->numpages;
3803: $this->swapMargins($this->booklet);
3804:
3805: $gvars = $this->getGraphicVars();
3806:
3807: $this->_beginpage($orientation, $format);
3808:
3809: $this->pageopen[$this->page] = true;
3810:
3811: $this->setGraphicVars($gvars);
3812:
3813: $this->setPageMark();
3814:
3815: $this->setHeader();
3816:
3817: $this->setGraphicVars($gvars);
3818:
3819: $this->setPageMark();
3820:
3821: $this->setTableHeader();
3822:
3823: $this->emptypagemrk[$this->page]= $this->pagelen[$this->page];
3824: }
3825:
3826: 3827: 3828: 3829: 3830: 3831: 3832: 3833:
3834: public function setPageMark() {
3835: $this->intmrk[$this->page] = $this->pagelen[$this->page];
3836: $this->bordermrk[$this->page] = $this->intmrk[$this->page];
3837: $this->setContentMark();
3838: }
3839:
3840: 3841: 3842: 3843: 3844: 3845: 3846:
3847: protected function setContentMark($page=0) {
3848: if ($page <= 0) {
3849: $page = $this->page;
3850: }
3851: if (isset($this->footerlen[$page])) {
3852: $this->cntmrk[$page] = $this->pagelen[$page] - $this->footerlen[$page];
3853: } else {
3854: $this->cntmrk[$page] = $this->pagelen[$page];
3855: }
3856: }
3857:
3858: 3859: 3860: 3861: 3862: 3863: 3864: 3865:
3866: public function ($ln='', $lw=0, $ht='', $hs='') {
3867: $this->header_logo = $ln;
3868: $this->header_logo_width = $lw;
3869: $this->header_title = $ht;
3870: $this->header_string = $hs;
3871: }
3872:
3873: 3874: 3875: 3876: 3877: 3878: 3879:
3880: public function () {
3881: $ret = array();
3882: $ret['logo'] = $this->header_logo;
3883: $ret['logo_width'] = $this->header_logo_width;
3884: $ret['title'] = $this->header_title;
3885: $ret['string'] = $this->header_string;
3886: return $ret;
3887: }
3888:
3889: 3890: 3891: 3892: 3893: 3894:
3895: public function ($hm=10) {
3896: $this->header_margin = $hm;
3897: }
3898:
3899: 3900: 3901: 3902: 3903: 3904:
3905: public function () {
3906: return $this->header_margin;
3907: }
3908:
3909: 3910: 3911: 3912: 3913: 3914:
3915: public function ($fm=10) {
3916: $this->footer_margin = $fm;
3917: }
3918:
3919: 3920: 3921: 3922: 3923: 3924:
3925: public function () {
3926: return $this->footer_margin;
3927: }
3928: 3929: 3930: 3931: 3932:
3933: public function ($val=true) {
3934: $this->print_header = $val;
3935: }
3936:
3937: 3938: 3939: 3940: 3941:
3942: public function ($val=true) {
3943: $this->print_footer = $val;
3944: }
3945:
3946: 3947: 3948: 3949: 3950:
3951: public function getImageRBX() {
3952: return $this->img_rb_x;
3953: }
3954:
3955: 3956: 3957: 3958: 3959:
3960: public function getImageRBY() {
3961: return $this->img_rb_y;
3962: }
3963:
3964: 3965: 3966: 3967: 3968:
3969: public function Header() {
3970: $ormargins = $this->getOriginalMargins();
3971: $headerfont = $this->getHeaderFont();
3972: $headerdata = $this->getHeaderData();
3973: if (($headerdata['logo']) AND ($headerdata['logo'] != K_BLANK_IMAGE)) {
3974: $this->Image(K_PATH_IMAGES.$headerdata['logo'], '', '', $headerdata['logo_width']);
3975: $imgy = $this->getImageRBY();
3976: } else {
3977: $imgy = $this->GetY();
3978: }
3979: $cell_height = round(($this->getCellHeightRatio() * $headerfont[2]) / $this->getScaleFactor(), 2);
3980:
3981: if ($this->getRTL()) {
3982: $header_x = $ormargins['right'] + ($headerdata['logo_width'] * 1.1);
3983: } else {
3984: $header_x = $ormargins['left'] + ($headerdata['logo_width'] * 1.1);
3985: }
3986: $this->SetTextColor(0, 0, 0);
3987:
3988: $this->SetFont($headerfont[0], 'B', $headerfont[2] + 1);
3989: $this->SetX($header_x);
3990: $this->Cell(0, $cell_height, $headerdata['title'], 0, 1, '', 0, '', 0);
3991:
3992: $this->SetFont($headerfont[0], $headerfont[1], $headerfont[2]);
3993: $this->SetX($header_x);
3994: $this->MultiCell(0, $cell_height, $headerdata['string'], 0, '', 0, 1, '', '', true, 0, false);
3995:
3996: $this->SetLineStyle(array('width' => 0.85 / $this->getScaleFactor(), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)));
3997: $this->SetY((2.835 / $this->getScaleFactor()) + max($imgy, $this->GetY()));
3998: if ($this->getRTL()) {
3999: $this->SetX($ormargins['right']);
4000: } else {
4001: $this->SetX($ormargins['left']);
4002: }
4003: $this->Cell(0, 0, '', 'T', 0, 'C');
4004: }
4005:
4006: 4007: 4008: 4009: 4010:
4011: public function () {
4012: $cur_y = $this->GetY();
4013: $ormargins = $this->getOriginalMargins();
4014: $this->SetTextColor(0, 0, 0);
4015:
4016: $line_width = 0.85 / $this->getScaleFactor();
4017: $this->SetLineStyle(array('width' => $line_width, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)));
4018:
4019: $barcode = $this->getBarcode();
4020: if (!empty($barcode)) {
4021: $this->Ln($line_width);
4022: $barcode_width = round(($this->getPageWidth() - $ormargins['left'] - $ormargins['right']) / 3);
4023: $style = array(
4024: 'position' => $this->rtl?'R':'L',
4025: 'align' => $this->rtl?'R':'L',
4026: 'stretch' => false,
4027: 'fitwidth' => true,
4028: 'cellfitalign' => '',
4029: 'border' => false,
4030: 'padding' => 0,
4031: 'fgcolor' => array(0,0,0),
4032: 'bgcolor' => false,
4033: 'text' => false
4034: );
4035: $this->write1DBarcode($barcode, 'C128B', '', $cur_y + $line_width, '', (($this->getFooterMargin() / 3) - $line_width), 0.3, $style, '');
4036: }
4037: if (empty($this->pagegroups)) {
4038: $pagenumtxt = $this->l['w_page'].' '.$this->getAliasNumPage().' / '.$this->getAliasNbPages();
4039: } else {
4040: $pagenumtxt = $this->l['w_page'].' '.$this->getPageNumGroupAlias().' / '.$this->getPageGroupAlias();
4041: }
4042: $this->SetY($cur_y);
4043:
4044: if ($this->getRTL()) {
4045: $this->SetX($ormargins['right']);
4046: $this->Cell(0, 0, $pagenumtxt, 'T', 0, 'L');
4047: } else {
4048: $this->SetX($ormargins['left']);
4049: $this->Cell(0, 0, $pagenumtxt, 'T', 0, 'R');
4050: }
4051: }
4052:
4053: 4054: 4055: 4056: 4057:
4058: protected function () {
4059: if ($this->print_header) {
4060: $this->setGraphicVars($this->default_graphic_vars);
4061: $temp_thead = $this->thead;
4062: $temp_theadMargins = $this->theadMargins;
4063: $lasth = $this->lasth;
4064: $this->_out('q');
4065: $this->rMargin = $this->original_rMargin;
4066: $this->lMargin = $this->original_lMargin;
4067: $this->SetCellPadding(0);
4068:
4069: if ($this->rtl) {
4070: $this->SetXY($this->original_rMargin, $this->header_margin);
4071: } else {
4072: $this->SetXY($this->original_lMargin, $this->header_margin);
4073: }
4074: $this->SetFont($this->header_font[0], $this->header_font[1], $this->header_font[2]);
4075: $this->Header();
4076:
4077: if ($this->rtl) {
4078: $this->SetXY($this->original_rMargin, $this->tMargin);
4079: } else {
4080: $this->SetXY($this->original_lMargin, $this->tMargin);
4081: }
4082: $this->_out('Q');
4083: $this->lasth = $lasth;
4084: $this->thead = $temp_thead;
4085: $this->theadMargins = $temp_theadMargins;
4086: $this->newline = false;
4087: }
4088: }
4089:
4090: 4091: 4092: 4093: 4094:
4095: protected function () {
4096:
4097:
4098: $gvars = $this->getGraphicVars();
4099:
4100: $this->footerpos[$this->page] = $this->pagelen[$this->page];
4101: $this->_out("\n");
4102: if ($this->print_footer) {
4103: $this->setGraphicVars($this->default_graphic_vars);
4104: $this->current_column = 0;
4105: $this->num_columns = 1;
4106: $temp_thead = $this->thead;
4107: $temp_theadMargins = $this->theadMargins;
4108: $lasth = $this->lasth;
4109: $this->_out('q');
4110: $this->rMargin = $this->original_rMargin;
4111: $this->lMargin = $this->original_lMargin;
4112: $this->SetCellPadding(0);
4113:
4114: $footer_y = $this->h - $this->footer_margin;
4115: if ($this->rtl) {
4116: $this->SetXY($this->original_rMargin, $footer_y);
4117: } else {
4118: $this->SetXY($this->original_lMargin, $footer_y);
4119: }
4120: $this->SetFont($this->footer_font[0], $this->footer_font[1], $this->footer_font[2]);
4121: $this->Footer();
4122:
4123: if ($this->rtl) {
4124: $this->SetXY($this->original_rMargin, $this->tMargin);
4125: } else {
4126: $this->SetXY($this->original_lMargin, $this->tMargin);
4127: }
4128: $this->_out('Q');
4129: $this->lasth = $lasth;
4130: $this->thead = $temp_thead;
4131: $this->theadMargins = $temp_theadMargins;
4132: }
4133:
4134: $this->setGraphicVars($gvars);
4135: $this->current_column = $gvars['current_column'];
4136: $this->num_columns = $gvars['num_columns'];
4137:
4138: $this->footerlen[$this->page] = $this->pagelen[$this->page] - $this->footerpos[$this->page] + 1;
4139: }
4140:
4141: 4142: 4143: 4144: 4145:
4146: protected function () {
4147: if ($this->num_columns > 1) {
4148:
4149: return;
4150: }
4151: if (isset($this->theadMargins['top'])) {
4152:
4153: $this->tMargin = $this->theadMargins['top'];
4154: $this->pagedim[$this->page]['tm'] = $this->tMargin;
4155: $this->y = $this->tMargin;
4156: }
4157: if (!$this->empty_string($this->thead) AND (!$this->inthead)) {
4158:
4159: $prev_lMargin = $this->lMargin;
4160: $prev_rMargin = $this->rMargin;
4161: $prev_cell_padding = $this->cell_padding;
4162: $this->lMargin = $this->theadMargins['lmargin'] + ($this->pagedim[$this->page]['olm'] - $this->pagedim[$this->theadMargins['page']]['olm']);
4163: $this->rMargin = $this->theadMargins['rmargin'] + ($this->pagedim[$this->page]['orm'] - $this->pagedim[$this->theadMargins['page']]['orm']);
4164: $this->cell_padding = $this->theadMargins['cell_padding'];
4165: if ($this->rtl) {
4166: $this->x = $this->w - $this->rMargin;
4167: } else {
4168: $this->x = $this->lMargin;
4169: }
4170:
4171: $this->writeHTML($this->thead, false, false, false, false, '');
4172:
4173: if (!isset($this->theadMargins['top'])) {
4174: $this->theadMargins['top'] = $this->tMargin;
4175: }
4176: $this->tMargin = $this->y;
4177: $this->pagedim[$this->page]['tm'] = $this->tMargin;
4178: $this->lasth = 0;
4179: $this->lMargin = $prev_lMargin;
4180: $this->rMargin = $prev_rMargin;
4181: $this->cell_padding = $prev_cell_padding;
4182: }
4183: }
4184:
4185: 4186: 4187: 4188: 4189: 4190: 4191:
4192: public function PageNo() {
4193: return $this->page;
4194: }
4195:
4196: 4197: 4198: 4199: 4200: 4201: 4202: 4203: 4204: 4205: 4206: 4207:
4208: public function AddSpotColor($name, $c, $m, $y, $k) {
4209: if (!isset($this->spot_colors[$name])) {
4210: $i = 1 + count($this->spot_colors);
4211: $this->spot_colors[$name] = array('i' => $i, 'c' => $c, 'm' => $m, 'y' => $y, 'k' => $k);
4212: }
4213: }
4214:
4215: 4216: 4217: 4218: 4219: 4220: 4221: 4222: 4223: 4224: 4225:
4226: public function SetDrawColorArray($color, $ret=false) {
4227: if (is_array($color)) {
4228: $color = array_values($color);
4229: $r = isset($color[0]) ? $color[0] : -1;
4230: $g = isset($color[1]) ? $color[1] : -1;
4231: $b = isset($color[2]) ? $color[2] : -1;
4232: $k = isset($color[3]) ? $color[3] : -1;
4233: if ($r >= 0) {
4234: return $this->SetDrawColor($r, $g, $b, $k, $ret);
4235: }
4236: }
4237: return '';
4238: }
4239:
4240: 4241: 4242: 4243: 4244: 4245: 4246: 4247: 4248: 4249: 4250: 4251:
4252: public function SetDrawColor($col1=0, $col2=-1, $col3=-1, $col4=-1, $ret=false) {
4253:
4254: if (!is_numeric($col1)) {
4255: $col1 = 0;
4256: }
4257: if (!is_numeric($col2)) {
4258: $col2 = -1;
4259: }
4260: if (!is_numeric($col3)) {
4261: $col3 = -1;
4262: }
4263: if (!is_numeric($col4)) {
4264: $col4 = -1;
4265: }
4266:
4267: if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) {
4268:
4269: $this->DrawColor = sprintf('%.3F G', $col1/255);
4270: $this->strokecolor = array('G' => $col1);
4271: } elseif ($col4 == -1) {
4272:
4273: $this->DrawColor = sprintf('%.3F %.3F %.3F RG', $col1/255, $col2/255, $col3/255);
4274: $this->strokecolor = array('R' => $col1, 'G' => $col2, 'B' => $col3);
4275: } else {
4276:
4277: $this->DrawColor = sprintf('%.3F %.3F %.3F %.3F K', $col1/100, $col2/100, $col3/100, $col4/100);
4278: $this->strokecolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4);
4279: }
4280: if ($this->page > 0) {
4281: if (!$ret) {
4282: $this->_out($this->DrawColor);
4283: }
4284: return $this->DrawColor;
4285: }
4286: return '';
4287: }
4288:
4289: 4290: 4291: 4292: 4293: 4294: 4295: 4296:
4297: public function SetDrawSpotColor($name, $tint=100) {
4298: if (!isset($this->spot_colors[$name])) {
4299: $this->Error('Undefined spot color: '.$name);
4300: }
4301: $this->DrawColor = sprintf('/CS%d CS %.3F SCN', $this->spot_colors[$name]['i'], $tint/100);
4302: if ($this->page > 0) {
4303: $this->_out($this->DrawColor);
4304: }
4305: }
4306:
4307: 4308: 4309: 4310: 4311: 4312: 4313: 4314: 4315:
4316: public function SetFillColorArray($color) {
4317: if (is_array($color)) {
4318: $color = array_values($color);
4319: $r = isset($color[0]) ? $color[0] : -1;
4320: $g = isset($color[1]) ? $color[1] : -1;
4321: $b = isset($color[2]) ? $color[2] : -1;
4322: $k = isset($color[3]) ? $color[3] : -1;
4323: if ($r >= 0) {
4324: $this->SetFillColor($r, $g, $b, $k);
4325: }
4326: }
4327: }
4328:
4329: 4330: 4331: 4332: 4333: 4334: 4335: 4336: 4337: 4338:
4339: public function SetFillColor($col1=0, $col2=-1, $col3=-1, $col4=-1) {
4340:
4341: if (!is_numeric($col1)) {
4342: $col1 = 0;
4343: }
4344: if (!is_numeric($col2)) {
4345: $col2 = -1;
4346: }
4347: if (!is_numeric($col3)) {
4348: $col3 = -1;
4349: }
4350: if (!is_numeric($col4)) {
4351: $col4 = -1;
4352: }
4353:
4354: if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) {
4355:
4356: $this->FillColor = sprintf('%.3F g', $col1/255);
4357: $this->bgcolor = array('G' => $col1);
4358: } elseif ($col4 == -1) {
4359:
4360: $this->FillColor = sprintf('%.3F %.3F %.3F rg', $col1/255, $col2/255, $col3/255);
4361: $this->bgcolor = array('R' => $col1, 'G' => $col2, 'B' => $col3);
4362: } else {
4363:
4364: $this->FillColor = sprintf('%.3F %.3F %.3F %.3F k', $col1/100, $col2/100, $col3/100, $col4/100);
4365: $this->bgcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4);
4366: }
4367: $this->ColorFlag = ($this->FillColor != $this->TextColor);
4368: if ($this->page > 0) {
4369: $this->_out($this->FillColor);
4370: }
4371: }
4372:
4373: 4374: 4375: 4376: 4377: 4378: 4379: 4380:
4381: public function SetFillSpotColor($name, $tint=100) {
4382: if (!isset($this->spot_colors[$name])) {
4383: $this->Error('Undefined spot color: '.$name);
4384: }
4385: $this->FillColor = sprintf('/CS%d cs %.3F scn', $this->spot_colors[$name]['i'], $tint/100);
4386: $this->ColorFlag = ($this->FillColor != $this->TextColor);
4387: if ($this->page > 0) {
4388: $this->_out($this->FillColor);
4389: }
4390: }
4391:
4392: 4393: 4394: 4395: 4396: 4397: 4398: 4399:
4400: public function SetTextColorArray($color) {
4401: if (is_array($color)) {
4402: $color = array_values($color);
4403: $r = isset($color[0]) ? $color[0] : -1;
4404: $g = isset($color[1]) ? $color[1] : -1;
4405: $b = isset($color[2]) ? $color[2] : -1;
4406: $k = isset($color[3]) ? $color[3] : -1;
4407: if ($r >= 0) {
4408: $this->SetTextColor($r, $g, $b, $k);
4409: }
4410: }
4411: }
4412:
4413: 4414: 4415: 4416: 4417: 4418: 4419: 4420: 4421: 4422:
4423: public function SetTextColor($col1=0, $col2=-1, $col3=-1, $col4=-1) {
4424:
4425: if (!is_numeric($col1)) {
4426: $col1 = 0;
4427: }
4428: if (!is_numeric($col2)) {
4429: $col2 = -1;
4430: }
4431: if (!is_numeric($col3)) {
4432: $col3 = -1;
4433: }
4434: if (!is_numeric($col4)) {
4435: $col4 = -1;
4436: }
4437:
4438: if (($col2 == -1) AND ($col3 == -1) AND ($col4 == -1)) {
4439:
4440: $this->TextColor = sprintf('%.3F g', $col1/255);
4441: $this->fgcolor = array('G' => $col1);
4442: } elseif ($col4 == -1) {
4443:
4444: $this->TextColor = sprintf('%.3F %.3F %.3F rg', $col1/255, $col2/255, $col3/255);
4445: $this->fgcolor = array('R' => $col1, 'G' => $col2, 'B' => $col3);
4446: } else {
4447:
4448: $this->TextColor = sprintf('%.3F %.3F %.3F %.3F k', $col1/100, $col2/100, $col3/100, $col4/100);
4449: $this->fgcolor = array('C' => $col1, 'M' => $col2, 'Y' => $col3, 'K' => $col4);
4450: }
4451: $this->ColorFlag = ($this->FillColor != $this->TextColor);
4452: }
4453:
4454: 4455: 4456: 4457: 4458: 4459: 4460: 4461:
4462: public function SetTextSpotColor($name, $tint=100) {
4463: if (!isset($this->spot_colors[$name])) {
4464: $this->Error('Undefined spot color: '.$name);
4465: }
4466: $this->TextColor = sprintf('/CS%d cs %.3F scn', $this->spot_colors[$name]['i'], $tint/100);
4467: $this->ColorFlag = ($this->FillColor != $this->TextColor);
4468: if ($this->page > 0) {
4469: $this->_out($this->TextColor);
4470: }
4471: }
4472:
4473: 4474: 4475: 4476: 4477: 4478: 4479: 4480: 4481: 4482: 4483: 4484:
4485: public function GetStringWidth($s, $fontname='', $fontstyle='', $fontsize=0, $getarray=false) {
4486: return $this->GetArrStringWidth($this->utf8Bidi($this->UTF8StringToArray($s), $s, $this->tmprtl), $fontname, $fontstyle, $fontsize, $getarray);
4487: }
4488:
4489: 4490: 4491: 4492: 4493: 4494: 4495: 4496: 4497: 4498: 4499: 4500:
4501: public function GetArrStringWidth($sa, $fontname='', $fontstyle='', $fontsize=0, $getarray=false) {
4502:
4503: if (!$this->empty_string($fontname)) {
4504: $prev_FontFamily = $this->FontFamily;
4505: $prev_FontStyle = $this->FontStyle;
4506: $prev_FontSizePt = $this->FontSizePt;
4507: $this->SetFont($fontname, $fontstyle, $fontsize);
4508: }
4509:
4510: $sa = $this->UTF8ArrToLatin1($sa);
4511: $w = 0;
4512: $wa = array();
4513: foreach ($sa as $ck => $char) {
4514:
4515: $cw = $this->GetCharWidth($char, isset($sa[($ck + 1)]));
4516: $wa[] = $cw;
4517: $w += $cw;
4518: }
4519:
4520: if (!$this->empty_string($fontname)) {
4521: $this->SetFont($prev_FontFamily, $prev_FontStyle, $prev_FontSizePt);
4522: }
4523: if ($getarray) {
4524: return $wa;
4525: }
4526: return $w;
4527: }
4528:
4529: 4530: 4531: 4532: 4533: 4534: 4535: 4536: 4537:
4538: public function GetCharWidth($char, $notlast=true) {
4539:
4540: $chw = $this->getRawCharWidth($char);
4541: if (($this->font_spacing != 0) AND $notlast) {
4542:
4543: $chw += $this->font_spacing;
4544: }
4545: if ($this->font_stretching != 100) {
4546:
4547: $chw *= ($this->font_stretching / 100);
4548: }
4549: return $chw;
4550: }
4551:
4552: 4553: 4554: 4555: 4556: 4557: 4558: 4559:
4560: public function getRawCharWidth($char) {
4561: if ($char == 173) {
4562:
4563: return (0);
4564: }
4565: $cw = &$this->CurrentFont['cw'];
4566: if (isset($cw[$char])) {
4567: $w = $cw[$char];
4568: } elseif (isset($this->CurrentFont['dw'])) {
4569:
4570: $w = $this->CurrentFont['dw'];
4571: } elseif (isset($cw[32])) {
4572:
4573: $w = $cw[32];
4574: } else {
4575: $w = 600;
4576: }
4577: return ($w * $this->FontSize / 1000);
4578: }
4579:
4580: 4581: 4582: 4583: 4584: 4585: 4586:
4587: public function GetNumChars($s) {
4588: if ($this->isUnicodeFont()) {
4589: return count($this->UTF8StringToArray($s));
4590: }
4591: return strlen($s);
4592: }
4593:
4594: 4595: 4596: 4597: 4598:
4599: protected function getFontsList() {
4600: $fontsdir = opendir($this->_getfontpath());
4601: while (($file = readdir($fontsdir)) !== false) {
4602: if (substr($file, -4) == '.php') {
4603: array_push($this->fontlist, strtolower(basename($file, '.php')));
4604: }
4605: }
4606: closedir($fontsdir);
4607: }
4608:
4609: 4610: 4611: 4612: 4613: 4614: 4615: 4616: 4617: 4618: 4619: 4620: 4621:
4622: public function AddFont($family, $style='', $fontfile='', $subset='default') {
4623: if ($subset === 'default') {
4624: $subset = $this->font_subsetting;
4625: }
4626: if ($this->empty_string($family)) {
4627: if (!$this->empty_string($this->FontFamily)) {
4628: $family = $this->FontFamily;
4629: } else {
4630: $this->Error('Empty font family');
4631: }
4632: }
4633:
4634: if (substr($family, -1) == 'I') {
4635: $style .= 'I';
4636: $family = substr($family, 0, -1);
4637: }
4638: if (substr($family, -1) == 'B') {
4639: $style .= 'B';
4640: $family = substr($family, 0, -1);
4641: }
4642:
4643: $family = strtolower($family);
4644: if ((!$this->isunicode) AND ($family == 'arial')) {
4645: $family = 'helvetica';
4646: }
4647: if (($family == 'symbol') OR ($family == 'zapfdingbats')) {
4648: $style = '';
4649: }
4650: $tempstyle = strtoupper($style);
4651: $style = '';
4652:
4653: if (strpos($tempstyle, 'U') !== false) {
4654: $this->underline = true;
4655: } else {
4656: $this->underline = false;
4657: }
4658:
4659: if (strpos($tempstyle, 'D') !== false) {
4660: $this->linethrough = true;
4661: } else {
4662: $this->linethrough = false;
4663: }
4664:
4665: if (strpos($tempstyle, 'O') !== false) {
4666: $this->overline = true;
4667: } else {
4668: $this->overline = false;
4669: }
4670:
4671: if (strpos($tempstyle, 'B') !== false) {
4672: $style .= 'B';
4673: }
4674:
4675: if (strpos($tempstyle, 'I') !== false) {
4676: $style .= 'I';
4677: }
4678: $bistyle = $style;
4679: $fontkey = $family.$style;
4680: $font_style = $style.($this->underline ? 'U' : '').($this->linethrough ? 'D' : '').($this->overline ? 'O' : '');
4681: $fontdata = array('fontkey' => $fontkey, 'family' => $family, 'style' => $font_style);
4682:
4683: $fb = $this->getFontBuffer($fontkey);
4684: if ($fb !== false) {
4685: if ($this->inxobj) {
4686:
4687: $this->xobjects[$this->xobjid]['fonts'][$fontkey] = $fb['i'];
4688: }
4689: return $fontdata;
4690: }
4691: if (isset($type)) {
4692: unset($type);
4693: }
4694: if (isset($cw)) {
4695: unset($cw);
4696: }
4697:
4698: $fontdir = false;
4699: if (!$this->empty_string($fontfile)) {
4700: $fontdir = dirname($fontfile);
4701: if ($this->empty_string($fontdir) OR ($fontdir == '.')) {
4702: $fontdir = '';
4703: } else {
4704: $fontdir .= '/';
4705: }
4706: }
4707:
4708: if ($this->empty_string($fontfile) OR (!file_exists($fontfile))) {
4709:
4710: $fontfile1 = str_replace(' ', '', $family).strtolower($style).'.php';
4711: $fontfile2 = str_replace(' ', '', $family).'.php';
4712:
4713: if (($fontdir !== false) AND file_exists($fontdir.$fontfile1)) {
4714: $fontfile = $fontdir.$fontfile1;
4715: } elseif (file_exists($this->_getfontpath().$fontfile1)) {
4716: $fontfile = $this->_getfontpath().$fontfile1;
4717: } elseif (file_exists($fontfile1)) {
4718: $fontfile = $fontfile1;
4719: } elseif (($fontdir !== false) AND file_exists($fontdir.$fontfile2)) {
4720: $fontfile = $fontdir.$fontfile2;
4721: } elseif (file_exists($this->_getfontpath().$fontfile2)) {
4722: $fontfile = $this->_getfontpath().$fontfile2;
4723: } else {
4724: $fontfile = $fontfile2;
4725: }
4726: }
4727:
4728: if (file_exists($fontfile)) {
4729: include($fontfile);
4730: } else {
4731: $this->Error('Could not include font definition file: '.$family.'');
4732: }
4733:
4734: if ((!isset($type)) OR (!isset($cw))) {
4735: $this->Error('The font definition file has a bad format: '.$fontfile.'');
4736: }
4737:
4738: if (!isset($file) OR $this->empty_string($file)) {
4739: $file = '';
4740: }
4741: if (!isset($enc) OR $this->empty_string($enc)) {
4742: $enc = '';
4743: }
4744: if (!isset($cidinfo) OR $this->empty_string($cidinfo)) {
4745: $cidinfo = array('Registry'=>'Adobe','Ordering'=>'Identity','Supplement'=>0);
4746: $cidinfo['uni2cid'] = array();
4747: }
4748: if (!isset($ctg) OR $this->empty_string($ctg)) {
4749: $ctg = '';
4750: }
4751: if (!isset($desc) OR $this->empty_string($desc)) {
4752: $desc = array();
4753: }
4754: if (!isset($up) OR $this->empty_string($up)) {
4755: $up = -100;
4756: }
4757: if (!isset($ut) OR $this->empty_string($ut)) {
4758: $ut = 50;
4759: }
4760: if (!isset($cw) OR $this->empty_string($cw)) {
4761: $cw = array();
4762: }
4763: if (!isset($dw) OR $this->empty_string($dw)) {
4764:
4765: if (isset($desc['MissingWidth']) AND ($desc['MissingWidth'] > 0)) {
4766: $dw = $desc['MissingWidth'];
4767: } elseif (isset($cw[32])) {
4768: $dw = $cw[32];
4769: } else {
4770: $dw = 600;
4771: }
4772: }
4773: ++$this->numfonts;
4774: if ($type == 'cidfont0') {
4775:
4776: $styles = array('' => '', 'B' => ',Bold', 'I' => ',Italic', 'BI' => ',BoldItalic');
4777: $sname = $name.$styles[$bistyle];
4778:
4779: if (strpos($bistyle, 'B') !== false) {
4780: if (isset($desc['StemV'])) {
4781: $desc['StemV'] *= 2;
4782: } else {
4783: $desc['StemV'] = 120;
4784: }
4785: }
4786:
4787: if (strpos($bistyle, 'I') !== false) {
4788: if (isset($desc['ItalicAngle'])) {
4789: $desc['ItalicAngle'] -= 11;
4790: } else {
4791: $desc['ItalicAngle'] = -11;
4792: }
4793: }
4794: } elseif ($type == 'core') {
4795: $name = $this->CoreFonts[$fontkey];
4796: $subset = false;
4797: } elseif (($type == 'TrueType') OR ($type == 'Type1')) {
4798: $subset = false;
4799: } elseif ($type == 'TrueTypeUnicode') {
4800: $enc = 'Identity-H';
4801: } else {
4802: $this->Error('Unknow font type: '.$type.'');
4803: }
4804:
4805: $subsetchars = array_fill(0, 256, true);
4806: $this->setFontBuffer($fontkey, array('fontkey' => $fontkey, 'i' => $this->numfonts, 'type' => $type, 'name' => $name, 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'dw' => $dw, 'enc' => $enc, 'cidinfo' => $cidinfo, 'file' => $file, 'ctg' => $ctg, 'subset' => $subset, 'subsetchars' => $subsetchars));
4807: if ($this->inxobj) {
4808:
4809: $this->xobjects[$this->xobjid]['fonts'][$fontkey] = $this->numfonts;
4810: }
4811: if (isset($diff) AND (!empty($diff))) {
4812:
4813: $d = 0;
4814: $nb = count($this->diffs);
4815: for ($i=1; $i <= $nb; ++$i) {
4816: if ($this->diffs[$i] == $diff) {
4817: $d = $i;
4818: break;
4819: }
4820: }
4821: if ($d == 0) {
4822: $d = $nb + 1;
4823: $this->diffs[$d] = $diff;
4824: }
4825: $this->setFontSubBuffer($fontkey, 'diff', $d);
4826: }
4827: if (!$this->empty_string($file)) {
4828: if (!isset($this->FontFiles[$file])) {
4829: if ((strcasecmp($type,'TrueType') == 0) OR (strcasecmp($type, 'TrueTypeUnicode') == 0)) {
4830: $this->FontFiles[$file] = array('length1' => $originalsize, 'fontdir' => $fontdir, 'subset' => $subset, 'fontkeys' => array($fontkey));
4831: } elseif ($type != 'core') {
4832: $this->FontFiles[$file] = array('length1' => $size1, 'length2' => $size2, 'fontdir' => $fontdir, 'subset' => $subset, 'fontkeys' => array($fontkey));
4833: }
4834: } else {
4835:
4836: $this->FontFiles[$file]['subset'] = ($this->FontFiles[$file]['subset'] AND $subset);
4837: if (!in_array($fontkey, $this->FontFiles[$file]['fontkeys'])) {
4838: $this->FontFiles[$file]['fontkeys'][] = $fontkey;
4839: }
4840: }
4841: }
4842: return $fontdata;
4843: }
4844:
4845: 4846: 4847: 4848: 4849: 4850: 4851: 4852: 4853: 4854: 4855: 4856: 4857: 4858: 4859: 4860:
4861: public function SetFont($family, $style='', $size=0, $fontfile='', $subset='default') {
4862:
4863: if ($size == 0) {
4864: $size = $this->FontSizePt;
4865: }
4866:
4867: $fontdata = $this->AddFont($family, $style, $fontfile, $subset);
4868: $this->FontFamily = $fontdata['family'];
4869: $this->FontStyle = $fontdata['style'];
4870: $this->CurrentFont = $this->getFontBuffer($fontdata['fontkey']);
4871: $this->SetFontSize($size);
4872: }
4873:
4874: 4875: 4876: 4877: 4878: 4879: 4880: 4881:
4882: public function SetFontSize($size, $out=true) {
4883:
4884: $this->FontSizePt = $size;
4885:
4886: $this->FontSize = $size / $this->k;
4887:
4888: if (isset($this->CurrentFont['desc']['FontBBox'])) {
4889: $bbox = explode(' ', substr($this->CurrentFont['desc']['FontBBox'], 1, -1));
4890: $font_height = ((intval($bbox[3]) - intval($bbox[1])) * $size / 1000);
4891: } else {
4892: $font_height = $size * 1.219;
4893: }
4894: if (isset($this->CurrentFont['desc']['Ascent']) AND ($this->CurrentFont['desc']['Ascent'] > 0)) {
4895: $font_ascent = ($this->CurrentFont['desc']['Ascent'] * $size / 1000);
4896: }
4897: if (isset($this->CurrentFont['desc']['Descent']) AND ($this->CurrentFont['desc']['Descent'] <= 0)) {
4898: $font_descent = (- $this->CurrentFont['desc']['Descent'] * $size / 1000);
4899: }
4900: if (!isset($font_ascent) AND !isset($font_descent)) {
4901:
4902: $font_ascent = 0.76 * $font_height;
4903: $font_descent = $font_height - $font_ascent;
4904: } elseif (!isset($font_descent)) {
4905: $font_descent = $font_height - $font_ascent;
4906: } elseif (!isset($font_ascent)) {
4907: $font_ascent = $font_height - $font_descent;
4908: }
4909: $this->FontAscent = $font_ascent / $this->k;
4910: $this->FontDescent = $font_descent / $this->k;
4911: if ($out AND ($this->page > 0) AND (isset($this->CurrentFont['i']))) {
4912: $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
4913: }
4914: }
4915:
4916: 4917: 4918: 4919: 4920: 4921: 4922: 4923: 4924: 4925:
4926: public function getFontDescent($font, $style='', $size=0) {
4927: $fontdata = $this->AddFont($font, $style);
4928: $fontinfo = $this->getFontBuffer($fontdata['fontkey']);
4929: if (isset($fontinfo['desc']['Descent']) AND ($fontinfo['desc']['Descent'] <= 0)) {
4930: $descent = (- $fontinfo['desc']['Descent'] * $size / 1000);
4931: } else {
4932: $descent = 1.219 * 0.24 * $size;
4933: }
4934: return ($descent / $this->k);
4935: }
4936:
4937: 4938: 4939: 4940: 4941: 4942: 4943: 4944: 4945: 4946:
4947: public function getFontAscent($font, $style='', $size=0) {
4948: $fontdata = $this->AddFont($font, $style);
4949: $fontinfo = $this->getFontBuffer($fontdata['fontkey']);
4950: if (isset($fontinfo['desc']['Ascent']) AND ($fontinfo['desc']['Ascent'] > 0)) {
4951: $ascent = ($fontinfo['desc']['Ascent'] * $size / 1000);
4952: } else {
4953: $ascent = 1.219 * 0.76 * $size;
4954: }
4955: return ($ascent / $this->k);
4956: }
4957:
4958: 4959: 4960: 4961: 4962: 4963:
4964: public function SetDefaultMonospacedFont($font) {
4965: $this->default_monospaced_font = $font;
4966: }
4967:
4968: 4969: 4970: 4971: 4972: 4973: 4974:
4975: public function AddLink() {
4976:
4977: $n = count($this->links) + 1;
4978: $this->links[$n] = array(0, 0);
4979: return $n;
4980: }
4981:
4982: 4983: 4984: 4985: 4986: 4987: 4988: 4989: 4990:
4991: public function SetLink($link, $y=0, $page=-1) {
4992: if ($y == -1) {
4993: $y = $this->y;
4994: }
4995: if ($page == -1) {
4996: $page = $this->page;
4997: }
4998: $this->links[$link] = array($page, $y);
4999: }
5000:
5001: 5002: 5003: 5004: 5005: 5006: 5007: 5008: 5009: 5010: 5011: 5012: 5013:
5014: public function Link($x, $y, $w, $h, $link, $spaces=0) {
5015: $this->Annotation($x, $y, $w, $h, $link, array('Subtype'=>'Link'), $spaces);
5016: }
5017:
5018: 5019: 5020: 5021: 5022: 5023: 5024: 5025: 5026: 5027: 5028: 5029: 5030:
5031: public function Annotation($x, $y, $w, $h, $text, $opt=array('Subtype'=>'Text'), $spaces=0) {
5032: if ($this->inxobj) {
5033:
5034: $this->xobjects[$this->xobjid]['annotations'][] = array('x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'text' => $text, 'opt' => $opt, 'spaces' => $spaces);
5035: return;
5036: }
5037: if ($x === '') {
5038: $x = $this->x;
5039: }
5040: if ($y === '') {
5041: $y = $this->y;
5042: }
5043:
5044: $this->checkPageRegions($h, $x, $y);
5045:
5046: if (isset($this->transfmatrix) AND !empty($this->transfmatrix)) {
5047: for ($i=$this->transfmatrix_key; $i > 0; --$i) {
5048: $maxid = count($this->transfmatrix[$i]) - 1;
5049: for ($j=$maxid; $j >= 0; --$j) {
5050: $ctm = $this->transfmatrix[$i][$j];
5051: if (isset($ctm['a'])) {
5052: $x = $x * $this->k;
5053: $y = ($this->h - $y) * $this->k;
5054: $w = $w * $this->k;
5055: $h = $h * $this->k;
5056:
5057: $xt = $x;
5058: $yt = $y;
5059: $x1 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
5060: $y1 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
5061:
5062: $xt = $x + $w;
5063: $yt = $y;
5064: $x2 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
5065: $y2 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
5066:
5067: $xt = $x;
5068: $yt = $y - $h;
5069: $x3 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
5070: $y3 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
5071:
5072: $xt = $x + $w;
5073: $yt = $y - $h;
5074: $x4 = ($ctm['a'] * $xt) + ($ctm['c'] * $yt) + $ctm['e'];
5075: $y4 = ($ctm['b'] * $xt) + ($ctm['d'] * $yt) + $ctm['f'];
5076:
5077: $x = min($x1, $x2, $x3, $x4);
5078: $y = max($y1, $y2, $y3, $y4);
5079: $w = (max($x1, $x2, $x3, $x4) - $x) / $this->k;
5080: $h = ($y - min($y1, $y2, $y3, $y4)) / $this->k;
5081: $x = $x / $this->k;
5082: $y = $this->h - ($y / $this->k);
5083: }
5084: }
5085: }
5086: }
5087: if ($this->page <= 0) {
5088: $page = 1;
5089: } else {
5090: $page = $this->page;
5091: }
5092: if (!isset($this->PageAnnots[$page])) {
5093: $this->PageAnnots[$page] = array();
5094: }
5095: ++$this->n;
5096: $this->PageAnnots[$page][] = array('n' => $this->n, 'x' => $x, 'y' => $y, 'w' => $w, 'h' => $h, 'txt' => $text, 'opt' => $opt, 'numspaces' => $spaces);
5097: if ((($opt['Subtype'] == 'FileAttachment') OR ($opt['Subtype'] == 'Sound')) AND (!$this->empty_string($opt['FS'])) AND file_exists($opt['FS']) AND (!isset($this->embeddedfiles[basename($opt['FS'])]))) {
5098: ++$this->n;
5099: $this->embeddedfiles[basename($opt['FS'])] = array('n' => $this->n, 'file' => $opt['FS']);
5100: }
5101:
5102: if (isset($opt['mk']['i']) AND file_exists($opt['mk']['i'])) {
5103: $this->Image($opt['mk']['i'], '', '', 10, 10, '', '', '', false, 300, '', false, false, 0, false, true);
5104: }
5105: if (isset($opt['mk']['ri']) AND file_exists($opt['mk']['ri'])) {
5106: $this->Image($opt['mk']['ri'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true);
5107: }
5108: if (isset($opt['mk']['ix']) AND file_exists($opt['mk']['ix'])) {
5109: $this->Image($opt['mk']['ix'], '', '', 0, 0, '', '', '', false, 300, '', false, false, 0, false, true);
5110: }
5111: }
5112:
5113: 5114: 5115: 5116: 5117: 5118:
5119: protected function _putEmbeddedFiles() {
5120: reset($this->embeddedfiles);
5121: foreach ($this->embeddedfiles as $filename => $filedata) {
5122: $data = file_get_contents($filedata['file']);
5123: $filter = '';
5124: if ($this->compress) {
5125: $data = gzcompress($data);
5126: $filter = ' /Filter /FlateDecode';
5127: }
5128: $stream = $this->_getrawstream($data, $filedata['n']);
5129: $out = $this->_getobj($filedata['n'])."\n";
5130: $out .= '<< /Type /EmbeddedFile'.$filter.' /Length '.strlen($stream).' >>';
5131: $out .= ' stream'."\n".$stream."\n".'endstream';
5132: $out .= "\n".'endobj';
5133: $this->_out($out);
5134: }
5135: }
5136:
5137: 5138: 5139: 5140: 5141: 5142: 5143: 5144: 5145: 5146: 5147: 5148: 5149: 5150: 5151: 5152: 5153: 5154: 5155: 5156: 5157: 5158: 5159: 5160:
5161: public function Text($x, $y, $txt, $fstroke=false, $fclip=false, $ffill=true, $border=0, $ln=0, $align='', $fill=false, $link='', $stretch=0, $ignore_min_height=false, $calign='T', $valign='M', $rtloff=false) {
5162: $textrendermode = $this->textrendermode;
5163: $textstrokewidth = $this->textstrokewidth;
5164: $this->setTextRenderingMode($fstroke, $ffill, $fclip);
5165: $this->SetXY($x, $y, $rtloff);
5166: $this->Cell(0, 0, $txt, $border, $ln, $align, $fill, $link, $stretch, $ignore_min_height, $calign, $valign);
5167:
5168: $this->textrendermode = $textrendermode;
5169: $this->textstrokewidth = $textstrokewidth;
5170: }
5171:
5172: 5173: 5174: 5175: 5176: 5177: 5178: 5179: 5180:
5181: public function AcceptPageBreak() {
5182: if ($this->num_columns > 1) {
5183:
5184: if($this->current_column < ($this->num_columns - 1)) {
5185:
5186: $this->selectColumn($this->current_column + 1);
5187: } else {
5188:
5189: $this->AddPage();
5190:
5191: $this->selectColumn(0);
5192: }
5193:
5194: return false;
5195: }
5196: return $this->AutoPageBreak;
5197: }
5198:
5199: 5200: 5201: 5202: 5203: 5204: 5205: 5206: 5207:
5208: protected function checkPageBreak($h=0, $y='', $addpage=true) {
5209: if ($this->empty_string($y)) {
5210: $y = $this->y;
5211: }
5212: $current_page = $this->page;
5213: if ((($y + $h) > $this->PageBreakTrigger) AND (!$this->InFooter) AND ($this->AcceptPageBreak())) {
5214: if ($addpage) {
5215:
5216: $x = $this->x;
5217: $this->AddPage($this->CurOrientation);
5218: $this->y = $this->tMargin;
5219: $oldpage = $this->page - 1;
5220: if ($this->rtl) {
5221: if ($this->pagedim[$this->page]['orm'] != $this->pagedim[$oldpage]['orm']) {
5222: $this->x = $x - ($this->pagedim[$this->page]['orm'] - $this->pagedim[$oldpage]['orm']);
5223: } else {
5224: $this->x = $x;
5225: }
5226: } else {
5227: if ($this->pagedim[$this->page]['olm'] != $this->pagedim[$oldpage]['olm']) {
5228: $this->x = $x + ($this->pagedim[$this->page]['olm'] - $this->pagedim[$oldpage]['olm']);
5229: } else {
5230: $this->x = $x;
5231: }
5232: }
5233: }
5234: $this->newline = true;
5235: return true;
5236: }
5237: if ($current_page != $this->page) {
5238:
5239: $this->newline = true;
5240: return true;
5241: }
5242: return false;
5243: }
5244:
5245: 5246: 5247: 5248: 5249: 5250: 5251: 5252: 5253: 5254: 5255: 5256: 5257: 5258: 5259: 5260:
5261: public function removeSHY($txt='') {
5262: $txt = preg_replace('/([\\xc2]{1}[\\xad]{1})/', '', $txt);
5263: if (!$this->isunicode) {
5264: $txt = preg_replace('/([\\xad]{1})/', '', $txt);
5265: }
5266: return $txt;
5267: }
5268:
5269: 5270: 5271: 5272: 5273: 5274: 5275: 5276: 5277: 5278: 5279: 5280: 5281: 5282: 5283: 5284: 5285: 5286: 5287:
5288: public function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='', $stretch=0, $ignore_min_height=false, $calign='T', $valign='M') {
5289: $prev_cell_margin = $this->cell_margin;
5290: $prev_cell_padding = $this->cell_padding;
5291: $this->adjustCellPadding($border);
5292: if (!$ignore_min_height) {
5293: $min_cell_height = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B'];
5294: if ($h < $min_cell_height) {
5295: $h = $min_cell_height;
5296: }
5297: }
5298: $this->checkPageBreak($h + $this->cell_margin['T'] + $this->cell_margin['B']);
5299: $this->_out($this->getCellCode($w, $h, $txt, $border, $ln, $align, $fill, $link, $stretch, true, $calign, $valign));
5300: $this->cell_padding = $prev_cell_padding;
5301: $this->cell_margin = $prev_cell_margin;
5302: }
5303:
5304: 5305: 5306: 5307: 5308: 5309: 5310: 5311: 5312: 5313: 5314: 5315: 5316: 5317: 5318: 5319: 5320: 5321: 5322: 5323:
5324: protected function getCellCode($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='', $stretch=0, $ignore_min_height=false, $calign='T', $valign='M') {
5325: $prev_cell_margin = $this->cell_margin;
5326: $prev_cell_padding = $this->cell_padding;
5327: $txt = $this->removeSHY($txt);
5328: $rs = '';
5329: $this->adjustCellPadding($border);
5330: if (!$ignore_min_height) {
5331: $min_cell_height = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B'];
5332: if ($h < $min_cell_height) {
5333: $h = $min_cell_height;
5334: }
5335: }
5336:
5337: $this->checkPageRegions($h);
5338: $k = $this->k;
5339: if ($this->rtl) {
5340: $x = $this->x - $this->cell_margin['R'];
5341: } else {
5342: $x = $this->x + $this->cell_margin['L'];
5343: }
5344: $y = $this->y + $this->cell_margin['T'];
5345: $prev_font_stretching = $this->font_stretching;
5346: $prev_font_spacing = $this->font_spacing;
5347:
5348: switch ($calign) {
5349: case 'A': {
5350:
5351: switch ($valign) {
5352: case 'T': {
5353:
5354: $y -= $this->cell_padding['T'];
5355: break;
5356: }
5357: case 'B': {
5358:
5359: $y -= ($h - $this->cell_padding['B'] - $this->FontAscent - $this->FontDescent);
5360: break;
5361: }
5362: default:
5363: case 'C':
5364: case 'M': {
5365:
5366: $y -= (($h - $this->FontAscent - $this->FontDescent) / 2);
5367: break;
5368: }
5369: }
5370: break;
5371: }
5372: case 'L': {
5373:
5374: switch ($valign) {
5375: case 'T': {
5376:
5377: $y -= ($this->cell_padding['T'] + $this->FontAscent);
5378: break;
5379: }
5380: case 'B': {
5381:
5382: $y -= ($h - $this->cell_padding['B'] - $this->FontDescent);
5383: break;
5384: }
5385: default:
5386: case 'C':
5387: case 'M': {
5388:
5389: $y -= (($h + $this->FontAscent - $this->FontDescent) / 2);
5390: break;
5391: }
5392: }
5393: break;
5394: }
5395: case 'D': {
5396:
5397: switch ($valign) {
5398: case 'T': {
5399:
5400: $y -= ($this->cell_padding['T'] + $this->FontAscent + $this->FontDescent);
5401: break;
5402: }
5403: case 'B': {
5404:
5405: $y -= ($h - $this->cell_padding['B']);
5406: break;
5407: }
5408: default:
5409: case 'C':
5410: case 'M': {
5411:
5412: $y -= (($h + $this->FontAscent + $this->FontDescent) / 2);
5413: break;
5414: }
5415: }
5416: break;
5417: }
5418: case 'B': {
5419:
5420: $y -= $h;
5421: break;
5422: }
5423: case 'C':
5424: case 'M': {
5425:
5426: $y -= ($h / 2);
5427: break;
5428: }
5429: default:
5430: case 'T': {
5431:
5432: break;
5433: }
5434: }
5435:
5436: switch ($valign) {
5437: case 'T': {
5438:
5439: $yt = $y + $this->cell_padding['T'];
5440: break;
5441: }
5442: case 'B': {
5443:
5444: $yt = $y + $h - $this->cell_padding['B'] - $this->FontAscent - $this->FontDescent;
5445: break;
5446: }
5447: default:
5448: case 'C':
5449: case 'M': {
5450:
5451: $yt = $y + (($h - $this->FontAscent - $this->FontDescent) / 2);
5452: break;
5453: }
5454: }
5455: $basefonty = $yt + $this->FontAscent;
5456: if ($this->empty_string($w) OR ($w <= 0)) {
5457: if ($this->rtl) {
5458: $w = $x - $this->lMargin;
5459: } else {
5460: $w = $this->w - $this->rMargin - $x;
5461: }
5462: }
5463: $s = '';
5464:
5465: if (is_string($border) AND (strlen($border) == 4)) {
5466:
5467: $border = 1;
5468: }
5469: if ($fill OR ($border == 1)) {
5470: if ($fill) {
5471: $op = ($border == 1) ? 'B' : 'f';
5472: } else {
5473: $op = 'S';
5474: }
5475: if ($this->rtl) {
5476: $xk = (($x - $w) * $k);
5477: } else {
5478: $xk = ($x * $k);
5479: }
5480: $s .= sprintf('%.2F %.2F %.2F %.2F re %s ', $xk, (($this->h - $y) * $k), ($w * $k), (-$h * $k), $op);
5481: }
5482:
5483: $s .= $this->getCellBorder($x, $y, $w, $h, $border);
5484: if ($txt != '') {
5485: $txt2 = $txt;
5486: if ($this->isunicode) {
5487: if (($this->CurrentFont['type'] == 'core') OR ($this->CurrentFont['type'] == 'TrueType') OR ($this->CurrentFont['type'] == 'Type1')) {
5488: $txt2 = $this->UTF8ToLatin1($txt2);
5489: } else {
5490: $unicode = $this->UTF8StringToArray($txt);
5491: $unicode = $this->utf8Bidi($unicode, '', $this->tmprtl);
5492: if (defined('K_THAI_TOPCHARS') AND (K_THAI_TOPCHARS == true)) {
5493:
5494:
5495:
5496: $topchar = array(3611, 3613, 3615, 3650, 3651, 3652);
5497: $topsym = array(3633, 3636, 3637, 3638, 3639, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662);
5498: $numchars = count($unicode);
5499: $unik = 0;
5500: $uniblock = array();
5501: $uniblock[$unik] = array();
5502: $uniblock[$unik][] = $unicode[0];
5503:
5504: for ($i = 1; $i < $numchars; ++$i) {
5505:
5506: if (in_array($unicode[$i], $topsym) AND (in_array($unicode[($i - 1)], $topsym) OR in_array($unicode[($i - 1)], $topchar))) {
5507:
5508: ++$unik;
5509: $uniblock[$unik] = array();
5510: $uniblock[$unik][] = $unicode[$i];
5511: ++$unik;
5512: $uniblock[$unik] = array();
5513: $unicode[$i] = 0x200b;
5514: } else {
5515: $uniblock[$unik][] = $unicode[$i];
5516: }
5517: }
5518:
5519: }
5520: $txt2 = $this->arrUTF8ToUTF16BE($unicode, false);
5521: }
5522: }
5523: $txt2 = $this->_escape($txt2);
5524:
5525: $txwidth = $this->GetStringWidth($txt);
5526: $width = $txwidth;
5527:
5528: if ($stretch > 0) {
5529:
5530: if ($width <= 0) {
5531: $ratio = 1;
5532: } else {
5533: $ratio = (($w - $this->cell_padding['L'] - $this->cell_padding['R']) / $width);
5534: }
5535:
5536: if (($ratio < 1) OR (($ratio > 1) AND (($stretch % 2) == 0))) {
5537:
5538: if ($stretch > 2) {
5539:
5540: $this->font_spacing += ($w - $this->cell_padding['L'] - $this->cell_padding['R'] - $width) / (max(($this->GetNumChars($txt) - 1), 1) * ($this->font_stretching / 100));
5541: } else {
5542:
5543: $this->font_stretching *= $ratio;
5544: }
5545:
5546: $width = $w - $this->cell_padding['L'] - $this->cell_padding['R'];
5547:
5548: $align = '';
5549: }
5550: }
5551: if ($this->font_stretching != 100) {
5552:
5553: $rs .= sprintf('BT %.2F Tz ET ', $this->font_stretching);
5554: }
5555: if ($this->font_spacing != 0) {
5556:
5557: $rs .= sprintf('BT %.2F Tc ET ', ($this->font_spacing * $this->k));
5558: }
5559: if ($this->ColorFlag) {
5560: $s .= 'q '.$this->TextColor.' ';
5561: }
5562:
5563: $s .= sprintf('BT %d Tr %.2F w ET ', $this->textrendermode, $this->textstrokewidth);
5564:
5565: $ns = substr_count($txt, chr(32));
5566:
5567: $spacewidth = 0;
5568: if (($align == 'J') AND ($ns > 0)) {
5569: if ($this->isUnicodeFont()) {
5570:
5571: $width = $this->GetStringWidth(str_replace(' ', '', $txt));
5572:
5573: $spacewidth = -1000 * ($w - $width - $this->cell_padding['L'] - $this->cell_padding['R']) / ($ns?$ns:1) / $this->FontSize;
5574: if ($this->font_stretching != 100) {
5575:
5576: $spacewidth /= ($this->font_stretching / 100);
5577: }
5578:
5579: $txt2 = str_replace(chr(0).chr(32), ') '.sprintf('%.3F', $spacewidth).' (', $txt2);
5580: $unicode_justification = true;
5581: } else {
5582:
5583: $width = $txwidth;
5584:
5585: $spacewidth = (($w - $width - $this->cell_padding['L'] - $this->cell_padding['R']) / ($ns?$ns:1)) * $this->k;
5586: if ($this->font_stretching != 100) {
5587:
5588: $spacewidth /= ($this->font_stretching / 100);
5589: }
5590:
5591: $rs .= sprintf('BT %.3F Tw ET ', $spacewidth);
5592: }
5593: $width = $w - $this->cell_padding['L'] - $this->cell_padding['R'];
5594: }
5595:
5596: $txt2 = str_replace("\r", ' ', $txt2);
5597: switch ($align) {
5598: case 'C': {
5599: $dx = ($w - $width) / 2;
5600: break;
5601: }
5602: case 'R': {
5603: if ($this->rtl) {
5604: $dx = $this->cell_padding['R'];
5605: } else {
5606: $dx = $w - $width - $this->cell_padding['R'];
5607: }
5608: break;
5609: }
5610: case 'L': {
5611: if ($this->rtl) {
5612: $dx = $w - $width - $this->cell_padding['L'];
5613: } else {
5614: $dx = $this->cell_padding['L'];
5615: }
5616: break;
5617: }
5618: case 'J':
5619: default: {
5620: if ($this->rtl) {
5621: $dx = $this->cell_padding['R'];
5622: } else {
5623: $dx = $this->cell_padding['L'];
5624: }
5625: break;
5626: }
5627: }
5628: if ($this->rtl) {
5629: $xdx = $x - $dx - $width;
5630: } else {
5631: $xdx = $x + $dx;
5632: }
5633: $xdk = $xdx * $k;
5634:
5635: $s .= sprintf('BT %.2F %.2F Td [(%s)] TJ ET', $xdk, (($this->h - $basefonty) * $k), $txt2);
5636: if (isset($uniblock)) {
5637:
5638: $xshift = 0;
5639: $ty = (($this->h - $basefonty + (0.2 * $this->FontSize)) * $k);
5640: $spw = (($w - $txwidth - $this->cell_padding['L'] - $this->cell_padding['R']) / ($ns?$ns:1));
5641: foreach ($uniblock as $uk => $uniarr) {
5642: if (($uk % 2) == 0) {
5643:
5644: if ($spacewidth != 0) {
5645:
5646: $xshift += (count(array_keys($uniarr, 32)) * $spw);
5647: }
5648: $xshift += $this->GetArrStringWidth($uniarr);
5649: } else {
5650:
5651: $topchr = $this->arrUTF8ToUTF16BE($uniarr, false);
5652: $topchr = $this->_escape($topchr);
5653: $s .= sprintf(' BT %.2F %.2F Td [(%s)] TJ ET', ($xdk + ($xshift * $k)), $ty, $topchr);
5654: }
5655: }
5656: }
5657: if ($this->underline) {
5658: $s .= ' '.$this->_dounderlinew($xdx, $basefonty, $width);
5659: }
5660: if ($this->linethrough) {
5661: $s .= ' '.$this->_dolinethroughw($xdx, $basefonty, $width);
5662: }
5663: if ($this->overline) {
5664: $s .= ' '.$this->_dooverlinew($xdx, $basefonty, $width);
5665: }
5666: if ($this->ColorFlag) {
5667: $s .= ' Q';
5668: }
5669: if ($link) {
5670: $this->Link($xdx, $yt, $width, ($this->FontAscent + $this->FontDescent), $link, $ns);
5671: }
5672: }
5673:
5674: if ($s) {
5675:
5676: $rs .= $s;
5677: if ($this->font_spacing != 0) {
5678:
5679: $rs .= ' BT 0 Tc ET';
5680: }
5681: if ($this->font_stretching != 100) {
5682:
5683: $rs .= ' BT 100 Tz ET';
5684: }
5685: }
5686:
5687: if (!$this->isUnicodeFont() AND ($align == 'J')) {
5688: $rs .= ' BT 0 Tw ET';
5689: }
5690:
5691: $this->font_stretching = $prev_font_stretching;
5692: $this->font_spacing = $prev_font_spacing;
5693: $this->lasth = $h;
5694: if ($ln > 0) {
5695:
5696: $this->y = $y + $h + $this->cell_margin['B'];
5697: if ($ln == 1) {
5698: if ($this->rtl) {
5699: $this->x = $this->w - $this->rMargin;
5700: } else {
5701: $this->x = $this->lMargin;
5702: }
5703: }
5704: } else {
5705:
5706: if ($this->rtl) {
5707: $this->x = $x - $w - $this->cell_margin['L'];
5708: } else {
5709: $this->x = $x + $w + $this->cell_margin['R'];
5710: }
5711: }
5712: $gstyles = ''.$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '.$this->FillColor."\n";
5713: $rs = $gstyles.$rs;
5714: $this->cell_padding = $prev_cell_padding;
5715: $this->cell_margin = $prev_cell_margin;
5716: return $rs;
5717: }
5718:
5719: 5720: 5721: 5722: 5723: 5724: 5725: 5726: 5727: 5728: 5729: 5730: 5731:
5732: protected function getCellBorder($x, $y, $w, $h, $brd) {
5733: $s = '';
5734: if (empty($brd)) {
5735: return $s;
5736: }
5737: if ($brd == 1) {
5738: $brd = array('LRTB' => true);
5739: }
5740:
5741: $k = $this->k;
5742: if ($this->rtl) {
5743: $xeL = ($x - $w) * $k;
5744: $xeR = $x * $k;
5745: } else {
5746: $xeL = $x * $k;
5747: $xeR = ($x + $w) * $k;
5748: }
5749: $yeL = (($this->h - ($y + $h)) * $k);
5750: $yeT = (($this->h - $y) * $k);
5751: $xeT = $xeL;
5752: $xeB = $xeR;
5753: $yeR = $yeT;
5754: $yeB = $yeL;
5755: if (is_string($brd)) {
5756:
5757: $slen = strlen($brd);
5758: $newbrd = array();
5759: for ($i = 0; $i < $slen; ++$i) {
5760: $newbrd[$brd{$i}] = array('cap' => 'square', 'join' => 'miter');
5761: }
5762: $brd = $newbrd;
5763: }
5764: if (isset($brd['mode'])) {
5765: $mode = $brd['mode'];
5766: unset($brd['mode']);
5767: } else {
5768: $mode = 'normal';
5769: }
5770: foreach ($brd as $border => $style) {
5771: if (is_array($style) AND !empty($style)) {
5772:
5773: $prev_style = $this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' ';
5774: $s .= $this->SetLineStyle($style, true)."\n";
5775: }
5776: switch ($mode) {
5777: case 'ext': {
5778: $off = (($this->LineWidth / 2) * $k);
5779: $xL = $xeL - $off;
5780: $xR = $xeR + $off;
5781: $yT = $yeT + $off;
5782: $yL = $yeL - $off;
5783: $xT = $xL;
5784: $xB = $xR;
5785: $yR = $yT;
5786: $yB = $yL;
5787: $w += $this->LineWidth;
5788: $h += $this->LineWidth;
5789: break;
5790: }
5791: case 'int': {
5792: $off = ($this->LineWidth / 2) * $k;
5793: $xL = $xeL + $off;
5794: $xR = $xeR - $off;
5795: $yT = $yeT - $off;
5796: $yL = $yeL + $off;
5797: $xT = $xL;
5798: $xB = $xR;
5799: $yR = $yT;
5800: $yB = $yL;
5801: $w -= $this->LineWidth;
5802: $h -= $this->LineWidth;
5803: break;
5804: }
5805: case 'normal':
5806: default: {
5807: $xL = $xeL;
5808: $xT = $xeT;
5809: $xB = $xeB;
5810: $xR = $xeR;
5811: $yL = $yeL;
5812: $yT = $yeT;
5813: $yB = $yeB;
5814: $yR = $yeR;
5815: break;
5816: }
5817: }
5818:
5819: if (strlen($border) == 4) {
5820: $s .= sprintf('%.2F %.2F %.2F %.2F re S ', $xT, $yT, ($w * $k), (-$h * $k));
5821: } elseif (strlen($border) == 3) {
5822: if (strpos($border,'B') === false) {
5823: $s .= sprintf('%.2F %.2F m ', $xL, $yL);
5824: $s .= sprintf('%.2F %.2F l ', $xT, $yT);
5825: $s .= sprintf('%.2F %.2F l ', $xR, $yR);
5826: $s .= sprintf('%.2F %.2F l ', $xB, $yB);
5827: $s .= 'S ';
5828: } elseif (strpos($border,'L') === false) {
5829: $s .= sprintf('%.2F %.2F m ', $xT, $yT);
5830: $s .= sprintf('%.2F %.2F l ', $xR, $yR);
5831: $s .= sprintf('%.2F %.2F l ', $xB, $yB);
5832: $s .= sprintf('%.2F %.2F l ', $xL, $yL);
5833: $s .= 'S ';
5834: } elseif (strpos($border,'T') === false) {
5835: $s .= sprintf('%.2F %.2F m ', $xR, $yR);
5836: $s .= sprintf('%.2F %.2F l ', $xB, $yB);
5837: $s .= sprintf('%.2F %.2F l ', $xL, $yL);
5838: $s .= sprintf('%.2F %.2F l ', $xT, $yT);
5839: $s .= 'S ';
5840: } elseif (strpos($border,'R') === false) {
5841: $s .= sprintf('%.2F %.2F m ', $xB, $yB);
5842: $s .= sprintf('%.2F %.2F l ', $xL, $yL);
5843: $s .= sprintf('%.2F %.2F l ', $xT, $yT);
5844: $s .= sprintf('%.2F %.2F l ', $xR, $yR);
5845: $s .= 'S ';
5846: }
5847: } elseif (strlen($border) == 2) {
5848: if ((strpos($border,'L') !== false) AND (strpos($border,'T') !== false)) {
5849: $s .= sprintf('%.2F %.2F m ', $xL, $yL);
5850: $s .= sprintf('%.2F %.2F l ', $xT, $yT);
5851: $s .= sprintf('%.2F %.2F l ', $xR, $yR);
5852: $s .= 'S ';
5853: } elseif ((strpos($border,'T') !== false) AND (strpos($border,'R') !== false)) {
5854: $s .= sprintf('%.2F %.2F m ', $xT, $yT);
5855: $s .= sprintf('%.2F %.2F l ', $xR, $yR);
5856: $s .= sprintf('%.2F %.2F l ', $xB, $yB);
5857: $s .= 'S ';
5858: } elseif ((strpos($border,'R') !== false) AND (strpos($border,'B') !== false)) {
5859: $s .= sprintf('%.2F %.2F m ', $xR, $yR);
5860: $s .= sprintf('%.2F %.2F l ', $xB, $yB);
5861: $s .= sprintf('%.2F %.2F l ', $xL, $yL);
5862: $s .= 'S ';
5863: } elseif ((strpos($border,'B') !== false) AND (strpos($border,'L') !== false)) {
5864: $s .= sprintf('%.2F %.2F m ', $xB, $yB);
5865: $s .= sprintf('%.2F %.2F l ', $xL, $yL);
5866: $s .= sprintf('%.2F %.2F l ', $xT, $yT);
5867: $s .= 'S ';
5868: } elseif ((strpos($border,'L') !== false) AND (strpos($border,'R') !== false)) {
5869: $s .= sprintf('%.2F %.2F m ', $xL, $yL);
5870: $s .= sprintf('%.2F %.2F l ', $xT, $yT);
5871: $s .= 'S ';
5872: $s .= sprintf('%.2F %.2F m ', $xR, $yR);
5873: $s .= sprintf('%.2F %.2F l ', $xB, $yB);
5874: $s .= 'S ';
5875: } elseif ((strpos($border,'T') !== false) AND (strpos($border,'B') !== false)) {
5876: $s .= sprintf('%.2F %.2F m ', $xT, $yT);
5877: $s .= sprintf('%.2F %.2F l ', $xR, $yR);
5878: $s .= 'S ';
5879: $s .= sprintf('%.2F %.2F m ', $xB, $yB);
5880: $s .= sprintf('%.2F %.2F l ', $xL, $yL);
5881: $s .= 'S ';
5882: }
5883: } else {
5884: if (strpos($border,'L') !== false) {
5885: $s .= sprintf('%.2F %.2F m ', $xL, $yL);
5886: $s .= sprintf('%.2F %.2F l ', $xT, $yT);
5887: $s .= 'S ';
5888: } elseif (strpos($border,'T') !== false) {
5889: $s .= sprintf('%.2F %.2F m ', $xT, $yT);
5890: $s .= sprintf('%.2F %.2F l ', $xR, $yR);
5891: $s .= 'S ';
5892: } elseif (strpos($border,'R') !== false) {
5893: $s .= sprintf('%.2F %.2F m ', $xR, $yR);
5894: $s .= sprintf('%.2F %.2F l ', $xB, $yB);
5895: $s .= 'S ';
5896: } elseif (strpos($border,'B') !== false) {
5897: $s .= sprintf('%.2F %.2F m ', $xB, $yB);
5898: $s .= sprintf('%.2F %.2F l ', $xL, $yL);
5899: $s .= 'S ';
5900: }
5901: }
5902: if (is_array($style) AND !empty($style)) {
5903:
5904: $s .= "\n".$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor."\n";
5905: }
5906: }
5907: return $s;
5908: }
5909:
5910: 5911: 5912: 5913: 5914: 5915: 5916: 5917: 5918: 5919: 5920: 5921: 5922: 5923: 5924: 5925: 5926: 5927: 5928: 5929: 5930: 5931: 5932: 5933: 5934:
5935: public function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false, $ln=1, $x='', $y='', $reseth=true, $stretch=0, $ishtml=false, $autopadding=true, $maxh=0, $valign='T', $fitcell=false) {
5936: $prev_cell_margin = $this->cell_margin;
5937: $prev_cell_padding = $this->cell_padding;
5938:
5939: $this->adjustCellPadding($border);
5940: $mc_padding = $this->cell_padding;
5941: $mc_margin = $this->cell_margin;
5942: $this->cell_padding['T'] = 0;
5943: $this->cell_padding['B'] = 0;
5944: $this->setCellMargins(0, 0, 0, 0);
5945: if ($this->empty_string($this->lasth) OR $reseth) {
5946:
5947: $this->resetLastH();
5948: }
5949: if (!$this->empty_string($y)) {
5950: $this->SetY($y);
5951: } else {
5952: $y = $this->GetY();
5953: }
5954: $resth = 0;
5955: if ((!$this->InFooter) AND (($y + $h + $mc_margin['T'] + $mc_margin['B']) > $this->PageBreakTrigger)) {
5956:
5957: $newh = $this->PageBreakTrigger - $y;
5958: $resth = $h - $newh;
5959: $h = $newh;
5960: }
5961:
5962: $startpage = $this->page;
5963:
5964: $startcolumn = $this->current_column;
5965: if (!$this->empty_string($x)) {
5966: $this->SetX($x);
5967: } else {
5968: $x = $this->GetX();
5969: }
5970:
5971: $this->checkPageRegions(0, $x, $y);
5972:
5973: $oy = $y + $mc_margin['T'];
5974: if ($this->rtl) {
5975: $ox = $this->w - $x - $mc_margin['R'];
5976: } else {
5977: $ox = $x + $mc_margin['L'];
5978: }
5979: $this->x = $ox;
5980: $this->y = $oy;
5981:
5982: if ($this->empty_string($w) OR ($w <= 0)) {
5983: if ($this->rtl) {
5984: $w = $this->x - $this->lMargin - $mc_margin['L'];
5985: } else {
5986: $w = $this->w - $this->x - $this->rMargin - $mc_margin['R'];
5987: }
5988: }
5989:
5990: $lMargin = $this->lMargin;
5991: $rMargin = $this->rMargin;
5992: if ($this->rtl) {
5993: $this->rMargin = $this->w - $this->x;
5994: $this->lMargin = $this->x - $w;
5995: } else {
5996: $this->lMargin = $this->x;
5997: $this->rMargin = $this->w - $this->x - $w;
5998: }
5999: if ($autopadding) {
6000:
6001: $this->y += $mc_padding['T'];
6002: }
6003: if ($ishtml) {
6004: $this->writeHTML($txt, true, 0, $reseth, true, $align);
6005: $nl = 1;
6006: } else {
6007:
6008: if ($maxh > 0) {
6009:
6010: $text_height = $this->getStringHeight($w, $txt, $reseth, $autopadding, $mc_padding, $border);
6011: if ($fitcell) {
6012: $prev_FontSizePt = $this->FontSizePt;
6013:
6014: $fmin = 1;
6015: $fmax = $this->FontSizePt;
6016: $prev_text_height = $text_height;
6017: $maxit = 100;
6018: while ($maxit > 0) {
6019: $fmid = (($fmax + $fmin) / 2);
6020: $this->SetFontSize($fmid, false);
6021: $this->resetLastH();
6022: $text_height = $this->getStringHeight($w, $txt, $reseth, $autopadding, $mc_padding, $border);
6023: if (($text_height == $maxh) OR (($text_height < $maxh) AND ($fmin >= ($fmax - 0.01)))) {
6024: break;
6025: } elseif ($text_height < $maxh) {
6026: $fmin = $fmid;
6027: } else {
6028: $fmax = $fmid;
6029: }
6030: --$maxit;
6031: }
6032: $this->SetFontSize($this->FontSizePt);
6033: }
6034: if ($text_height < $maxh) {
6035: if ($valign == 'M') {
6036:
6037: $this->y += (($maxh - $text_height) / 2);
6038: } elseif ($valign == 'B') {
6039:
6040: $this->y += ($maxh - $text_height);
6041: }
6042: }
6043: }
6044: $nl = $this->Write($this->lasth, $txt, '', 0, $align, true, $stretch, false, true, $maxh, 0, $mc_margin);
6045: if ($fitcell) {
6046:
6047: $this->SetFontSize($prev_FontSizePt);
6048: }
6049: }
6050: if ($autopadding) {
6051:
6052: $this->y += $mc_padding['B'];
6053: }
6054:
6055: $currentY = $this->y;
6056:
6057: $endpage = $this->page;
6058: if ($resth > 0) {
6059: $skip = ($endpage - $startpage);
6060: $tmpresth = $resth;
6061: while ($tmpresth > 0) {
6062: if ($skip <= 0) {
6063:
6064: $this->checkPageBreak($this->PageBreakTrigger + 1);
6065: }
6066: if ($this->num_columns > 1) {
6067: $tmpresth -= ($this->h - $this->y - $this->bMargin);
6068: } else {
6069: $tmpresth -= ($this->h - $this->tMargin - $this->bMargin);
6070: }
6071: --$skip;
6072: }
6073: $currentY = $this->y;
6074: $endpage = $this->page;
6075: }
6076:
6077: $endcolumn = $this->current_column;
6078: if ($this->num_columns == 0) {
6079: $this->num_columns = 1;
6080: }
6081:
6082: $border_start = $this->getBorderMode($border, $position='start');
6083: $border_end = $this->getBorderMode($border, $position='end');
6084: $border_middle = $this->getBorderMode($border, $position='middle');
6085:
6086: for ($page = $startpage; $page <= $endpage; ++$page) {
6087: $ccode = '';
6088: $this->setPage($page);
6089: if ($this->num_columns < 2) {
6090:
6091: $this->SetX($x);
6092: $this->y = $this->tMargin;
6093: }
6094:
6095: if ($page > $startpage) {
6096: if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) {
6097: $this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']);
6098: } elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) {
6099: $this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']);
6100: }
6101: }
6102: if ($startpage == $endpage) {
6103:
6104: for ($column = $startcolumn; $column <= $endcolumn; ++$column) {
6105: $this->selectColumn($column);
6106: if ($this->rtl) {
6107: $this->x -= $mc_margin['R'];
6108: } else {
6109: $this->x += $mc_margin['L'];
6110: }
6111: if ($startcolumn == $endcolumn) {
6112: $cborder = $border;
6113: $h = max($h, ($currentY - $oy));
6114: $this->y = $oy;
6115: } elseif ($column == $startcolumn) {
6116: $cborder = $border_start;
6117: $this->y = $oy;
6118: $h = $this->h - $this->y - $this->bMargin;
6119: } elseif ($column == $endcolumn) {
6120: $cborder = $border_end;
6121: $h = $currentY - $this->y;
6122: if ($resth > $h) {
6123: $h = $resth;
6124: }
6125: } else {
6126: $cborder = $border_middle;
6127: $h = $this->h - $this->y - $this->bMargin;
6128: $resth -= $h;
6129: }
6130: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
6131: }
6132: } elseif ($page == $startpage) {
6133: for ($column = $startcolumn; $column < $this->num_columns; ++$column) {
6134: $this->selectColumn($column);
6135: if ($this->rtl) {
6136: $this->x -= $mc_margin['R'];
6137: } else {
6138: $this->x += $mc_margin['L'];
6139: }
6140: if ($column == $startcolumn) {
6141: $cborder = $border_start;
6142: $this->y = $oy;
6143: $h = $this->h - $this->y - $this->bMargin;
6144: } else {
6145: $cborder = $border_middle;
6146: $h = $this->h - $this->y - $this->bMargin;
6147: $resth -= $h;
6148: }
6149: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
6150: }
6151: } elseif ($page == $endpage) {
6152: for ($column = 0; $column <= $endcolumn; ++$column) {
6153: $this->selectColumn($column);
6154: if ($this->rtl) {
6155: $this->x -= $mc_margin['R'];
6156: } else {
6157: $this->x += $mc_margin['L'];
6158: }
6159: if ($column == $endcolumn) {
6160:
6161: $cborder = $border_end;
6162: $h = $currentY - $this->y;
6163: if ($resth > $h) {
6164: $h = $resth;
6165: }
6166: } else {
6167:
6168: $cborder = $border_middle;
6169: $h = $this->h - $this->y - $this->bMargin;
6170: $resth -= $h;
6171: }
6172: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
6173: }
6174: } else {
6175: for ($column = 0; $column < $this->num_columns; ++$column) {
6176: $this->selectColumn($column);
6177: if ($this->rtl) {
6178: $this->x -= $mc_margin['R'];
6179: } else {
6180: $this->x += $mc_margin['L'];
6181: }
6182: $cborder = $border_middle;
6183: $h = $this->h - $this->y - $this->bMargin;
6184: $resth -= $h;
6185: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
6186: }
6187: }
6188: if ($cborder OR $fill) {
6189:
6190: if ($this->inxobj) {
6191:
6192: if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) {
6193: $pagemarkkey = key($this->xobjects[$this->xobjid]['transfmrk']);
6194: $pagemark = &$this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey];
6195: } else {
6196: $pagemark = &$this->xobjects[$this->xobjid]['intmrk'];
6197: }
6198: $pagebuff = $this->xobjects[$this->xobjid]['outdata'];
6199: $pstart = substr($pagebuff, 0, $pagemark);
6200: $pend = substr($pagebuff, $pagemark);
6201: $this->xobjects[$this->xobjid]['outdata'] = $pstart.$ccode.$pend;
6202: $pagemark += strlen($ccode);
6203: } else {
6204: if (end($this->transfmrk[$this->page]) !== false) {
6205: $pagemarkkey = key($this->transfmrk[$this->page]);
6206: $pagemark = &$this->transfmrk[$this->page][$pagemarkkey];
6207: } elseif ($this->InFooter) {
6208: $pagemark = &$this->footerpos[$this->page];
6209: } else {
6210: $pagemark = &$this->intmrk[$this->page];
6211: }
6212: $pagebuff = $this->getPageBuffer($this->page);
6213: $pstart = substr($pagebuff, 0, $pagemark);
6214: $pend = substr($pagebuff, $pagemark);
6215: $this->setPageBuffer($this->page, $pstart.$ccode.$pend);
6216: $pagemark += strlen($ccode);
6217: }
6218: }
6219: }
6220:
6221: $currentY = $this->GetY();
6222:
6223: $this->SetLeftMargin($lMargin);
6224: $this->SetRightMargin($rMargin);
6225: if ($ln > 0) {
6226:
6227: $this->SetY($currentY + $mc_margin['B']);
6228: if ($ln == 2) {
6229: $this->SetX($x + $w + $mc_margin['L'] + $mc_margin['R']);
6230: }
6231: } else {
6232:
6233: $this->setPage($startpage);
6234: $this->y = $y;
6235: $this->SetX($x + $w + $mc_margin['L'] + $mc_margin['R']);
6236: }
6237: $this->setContentMark();
6238: $this->cell_padding = $prev_cell_padding;
6239: $this->cell_margin = $prev_cell_margin;
6240: return $nl;
6241: }
6242:
6243: 6244: 6245: 6246: 6247: 6248: 6249: 6250:
6251: protected function getBorderMode($brd, $position='start') {
6252: if ((!$this->opencell) OR empty($brd)) {
6253: return $brd;
6254: }
6255: if ($brd == 1) {
6256: $brd = 'LTRB';
6257: }
6258: if (is_string($brd)) {
6259:
6260: $slen = strlen($brd);
6261: $newbrd = array();
6262: for ($i = 0; $i < $slen; ++$i) {
6263: $newbrd[$brd{$i}] = array('cap' => 'square', 'join' => 'miter');
6264: }
6265: $brd = $newbrd;
6266: }
6267: foreach ($brd as $border => $style) {
6268: switch ($position) {
6269: case 'start': {
6270: if (strpos($border, 'B') !== false) {
6271:
6272: $newkey = str_replace('B', '', $border);
6273: if (strlen($newkey) > 0) {
6274: $brd[$newkey] = $style;
6275: }
6276: unset($brd[$border]);
6277: }
6278: break;
6279: }
6280: case 'middle': {
6281: if (strpos($border, 'B') !== false) {
6282:
6283: $newkey = str_replace('B', '', $border);
6284: if (strlen($newkey) > 0) {
6285: $brd[$newkey] = $style;
6286: }
6287: unset($brd[$border]);
6288: $border = $newkey;
6289: }
6290: if (strpos($border, 'T') !== false) {
6291:
6292: $newkey = str_replace('T', '', $border);
6293: if (strlen($newkey) > 0) {
6294: $brd[$newkey] = $style;
6295: }
6296: unset($brd[$border]);
6297: }
6298: break;
6299: }
6300: case 'end': {
6301: if (strpos($border, 'T') !== false) {
6302:
6303: $newkey = str_replace('T', '', $border);
6304: if (strlen($newkey) > 0) {
6305: $brd[$newkey] = $style;
6306: }
6307: unset($brd[$border]);
6308: }
6309: break;
6310: }
6311: }
6312: }
6313: return $brd;
6314: }
6315:
6316: 6317: 6318: 6319: 6320: 6321: 6322: 6323: 6324: 6325: 6326: 6327: 6328:
6329: public function getNumLines($txt, $w=0, $reseth=false, $autopadding=true, $cellpadding='', $border=0) {
6330: if ($txt === '') {
6331:
6332: return 1;
6333: }
6334:
6335: $prev_cell_padding = $this->cell_padding;
6336: $prev_lasth = $this->lasth;
6337: if (is_array($cellpadding)) {
6338: $this->cell_padding = $cellpadding;
6339: }
6340: $this->adjustCellPadding($border);
6341: if ($this->empty_string($w) OR ($w <= 0)) {
6342: if ($this->rtl) {
6343: $w = $this->x - $this->lMargin;
6344: } else {
6345: $w = $this->w - $this->rMargin - $this->x;
6346: }
6347: }
6348: $wmax = $w - $this->cell_padding['L'] - $this->cell_padding['R'];
6349: if ($reseth) {
6350:
6351: $this->resetLastH();
6352: }
6353: $lines = 1;
6354: $sum = 0;
6355: $chars = $this->utf8Bidi($this->UTF8StringToArray($txt), $txt, $this->tmprtl);
6356: $charsWidth = $this->GetArrStringWidth($chars, '', '', 0, true);
6357: $length = count($chars);
6358: $lastSeparator = -1;
6359: for ($i = 0; $i < $length; ++$i) {
6360: $charWidth = $charsWidth[$i];
6361: if (preg_match($this->re_spaces, $this->unichr($chars[$i]))) {
6362: $lastSeparator = $i;
6363: }
6364: if ((($sum + $charWidth) > $wmax) OR ($chars[$i] == 10)) {
6365: ++$lines;
6366: if ($lastSeparator != -1) {
6367: $i = $lastSeparator;
6368: $lastSeparator = -1;
6369: $sum = 0;
6370: } else {
6371: $sum = $charWidth;
6372: }
6373: } else {
6374: $sum += $charWidth;
6375: }
6376: }
6377: if ($chars[($length - 1)] == 10) {
6378: --$lines;
6379: }
6380: $this->cell_padding = $prev_cell_padding;
6381: $this->lasth = $prev_lasth;
6382: return $lines;
6383: }
6384:
6385: 6386: 6387: 6388: 6389: 6390: 6391: 6392: 6393: 6394: 6395: 6396: 6397: 6398: 6399: 6400: 6401: 6402: 6403: 6404: 6405: 6406: 6407: 6408: 6409: 6410: 6411: 6412: 6413: 6414: 6415: 6416: 6417: 6418: 6419: 6420: 6421: 6422: 6423: 6424: 6425: 6426: 6427: 6428: 6429: 6430: 6431:
6432: public function getStringHeight($w, $txt, $reseth=false, $autopadding=true, $cellpadding='', $border=0) {
6433:
6434: $prev_cell_padding = $this->cell_padding;
6435: $prev_lasth = $this->lasth;
6436: if (is_array($cellpadding)) {
6437: $this->cell_padding = $cellpadding;
6438: }
6439: $this->adjustCellPadding($border);
6440: $lines = $this->getNumLines($txt, $w, $reseth, $autopadding, $cellpadding, $border);
6441: $height = $lines * ($this->FontSize * $this->cell_height_ratio);
6442: if ($autopadding) {
6443:
6444: $height += ($this->cell_padding['T'] + $this->cell_padding['B']);
6445: }
6446: $this->cell_padding = $prev_cell_padding;
6447: $this->lasth = $prev_lasth;
6448: return $height;
6449: }
6450:
6451: 6452: 6453: 6454: 6455: 6456: 6457: 6458: 6459: 6460: 6461: 6462: 6463: 6464: 6465: 6466: 6467: 6468:
6469: public function Write($h, $txt, $link='', $fill=false, $align='', $ln=false, $stretch=0, $firstline=false, $firstblock=false, $maxh=0, $wadj=0, $margin='') {
6470:
6471: $this->checkPageRegions($h);
6472: if (strlen($txt) == 0) {
6473:
6474: $txt = ' ';
6475: }
6476: if ($margin === '') {
6477:
6478: $margin = $this->cell_margin;
6479: }
6480:
6481: $s = str_replace("\r", '', $txt);
6482:
6483: if (preg_match($this->unicode->uni_RE_PATTERN_ARABIC, $s)) {
6484: $arabic = true;
6485: } else {
6486: $arabic = false;
6487: }
6488:
6489: if ($arabic OR ($this->tmprtl == 'R') OR preg_match($this->unicode->uni_RE_PATTERN_RTL, $s)) {
6490: $rtlmode = true;
6491: } else {
6492: $rtlmode = false;
6493: }
6494:
6495: $chrwidth = $this->GetCharWidth('.');
6496:
6497: $chars = $this->UTF8StringToArray($s);
6498:
6499: $uchars = $this->UTF8ArrayToUniArray($chars);
6500:
6501: $nb = count($chars);
6502:
6503: $shy_replacement = 45;
6504: $shy_replacement_char = $this->unichr($shy_replacement);
6505:
6506: $shy_replacement_width = $this->GetCharWidth($shy_replacement);
6507:
6508: $maxy = $this->y + $maxh - $h - $this->cell_padding['T'] - $this->cell_padding['B'];
6509:
6510: if ($this->rtl) {
6511: $w = $this->x - $this->lMargin;
6512: } else {
6513: $w = $this->w - $this->rMargin - $this->x;
6514: }
6515:
6516: $wmax = $w - $wadj;
6517: if (!$firstline) {
6518: $wmax -= ($this->cell_padding['L'] + $this->cell_padding['R']);
6519: }
6520: if ((!$firstline) AND (($chrwidth > $wmax) OR ($this->GetCharWidth($chars[0]) > $wmax))) {
6521:
6522: return '';
6523: }
6524:
6525: $row_height = max($h, $this->FontSize * $this->cell_height_ratio);
6526: $start_page = $this->page;
6527: $i = 0;
6528: $j = 0;
6529: $sep = -1;
6530: $shy = false;
6531: $l = 0;
6532: $nl = 0;
6533: $linebreak = false;
6534: $pc = 0;
6535:
6536: while ($i < $nb) {
6537: if (($maxh > 0) AND ($this->y >= $maxy) ) {
6538: break;
6539: }
6540:
6541: $c = $chars[$i];
6542: if ($c == 10) {
6543:
6544: if ($align == 'J') {
6545: if ($this->rtl) {
6546: $talign = 'R';
6547: } else {
6548: $talign = 'L';
6549: }
6550: } else {
6551: $talign = $align;
6552: }
6553: $tmpstr = $this->UniArrSubString($uchars, $j, $i);
6554: if ($firstline) {
6555: $startx = $this->x;
6556: $tmparr = array_slice($chars, $j, ($i - $j));
6557: if ($rtlmode) {
6558: $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
6559: }
6560: $linew = $this->GetArrStringWidth($tmparr);
6561: unset($tmparr);
6562: if ($this->rtl) {
6563: $this->endlinex = $startx - $linew;
6564: } else {
6565: $this->endlinex = $startx + $linew;
6566: }
6567: $w = $linew;
6568: $tmpcellpadding = $this->cell_padding;
6569: if ($maxh == 0) {
6570: $this->SetCellPadding(0);
6571: }
6572: }
6573: if ($firstblock AND $this->isRTLTextDir()) {
6574: $tmpstr = $this->stringRightTrim($tmpstr);
6575: }
6576:
6577: if (!empty($tmpstr) OR ($this->y < ($this->PageBreakTrigger - $row_height))) {
6578: $this->Cell($w, $h, $tmpstr, 0, 1, $talign, $fill, $link, $stretch);
6579: }
6580: unset($tmpstr);
6581: if ($firstline) {
6582: $this->cell_padding = $tmpcellpadding;
6583: return ($this->UniArrSubString($uchars, $i));
6584: }
6585: ++$nl;
6586: $j = $i + 1;
6587: $l = 0;
6588: $sep = -1;
6589: $shy = false;
6590:
6591: if ((($this->y + $this->lasth) > $this->PageBreakTrigger) AND (!$this->InFooter)) {
6592: $this->AcceptPageBreak();
6593: if ($this->rtl) {
6594: $this->x -= $margin['R'];
6595: } else {
6596: $this->x += $margin['L'];
6597: }
6598: $this->lMargin += $margin['L'];
6599: $this->rMargin += $margin['R'];
6600: }
6601: $w = $this->getRemainingWidth();
6602: $wmax = $w - $this->cell_padding['L'] - $this->cell_padding['R'];
6603: } else {
6604:
6605:
6606:
6607:
6608:
6609: if (($c != 160) AND (($c == 173) OR preg_match($this->re_spaces, $this->unichr($c)))) {
6610:
6611: $sep = $i;
6612:
6613: if ($c == 173) {
6614: $shy = true;
6615: if ($pc == 45) {
6616: $tmp_shy_replacement_width = 0;
6617: $tmp_shy_replacement_char = '';
6618: } else {
6619: $tmp_shy_replacement_width = $shy_replacement_width;
6620: $tmp_shy_replacement_char = $shy_replacement_char;
6621: }
6622: } else {
6623: $shy = false;
6624: }
6625: }
6626:
6627: if ($this->isUnicodeFont() AND ($arabic)) {
6628:
6629:
6630: $l = $this->GetArrStringWidth($this->utf8Bidi(array_slice($chars, $j, ($i - $j)), '', $this->tmprtl));
6631: } else {
6632: $l += $this->GetCharWidth($c);
6633: }
6634: if (($l > $wmax) OR (($c == 173) AND (($l + $tmp_shy_replacement_width) > $wmax)) ) {
6635:
6636: if ($sep == -1) {
6637:
6638: if (($this->rtl AND ($this->x <= ($this->w - $this->rMargin - $chrwidth)))
6639: OR ((!$this->rtl) AND ($this->x >= ($this->lMargin + $chrwidth)))) {
6640:
6641: $this->Cell($w, $h, '', 0, 1);
6642: $linebreak = true;
6643: if ($firstline) {
6644: return ($this->UniArrSubString($uchars, $j));
6645: }
6646: } else {
6647:
6648: $tmpstr = $this->UniArrSubString($uchars, $j, $i);
6649: if ($firstline) {
6650: $startx = $this->x;
6651: $tmparr = array_slice($chars, $j, ($i - $j));
6652: if ($rtlmode) {
6653: $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
6654: }
6655: $linew = $this->GetArrStringWidth($tmparr);
6656: unset($tmparr);
6657: if ($this->rtl) {
6658: $this->endlinex = $startx - $linew;
6659: } else {
6660: $this->endlinex = $startx + $linew;
6661: }
6662: $w = $linew;
6663: $tmpcellpadding = $this->cell_padding;
6664: if ($maxh == 0) {
6665: $this->SetCellPadding(0);
6666: }
6667: }
6668: if ($firstblock AND $this->isRTLTextDir()) {
6669: $tmpstr = $this->stringRightTrim($tmpstr);
6670: }
6671: $this->Cell($w, $h, $tmpstr, 0, 1, $align, $fill, $link, $stretch);
6672: unset($tmpstr);
6673: if ($firstline) {
6674: $this->cell_padding = $tmpcellpadding;
6675: return ($this->UniArrSubString($uchars, $i));
6676: }
6677: $j = $i;
6678: --$i;
6679: }
6680: } else {
6681:
6682: if ($this->rtl AND (!$firstblock) AND ($sep < $i)) {
6683: $endspace = 1;
6684: } else {
6685: $endspace = 0;
6686: }
6687: if ($shy) {
6688:
6689: $shy_width = $tmp_shy_replacement_width;
6690: if ($this->rtl) {
6691: $shy_char_left = $tmp_shy_replacement_char;
6692: $shy_char_right = '';
6693: } else {
6694: $shy_char_left = '';
6695: $shy_char_right = $tmp_shy_replacement_char;
6696: }
6697: } else {
6698: $shy_width = 0;
6699: $shy_char_left = '';
6700: $shy_char_right = '';
6701: }
6702: $tmpstr = $this->UniArrSubString($uchars, $j, ($sep + $endspace));
6703: if ($firstline) {
6704: $startx = $this->x;
6705: $tmparr = array_slice($chars, $j, (($sep + $endspace) - $j));
6706: if ($rtlmode) {
6707: $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
6708: }
6709: $linew = $this->GetArrStringWidth($tmparr);
6710: unset($tmparr);
6711: if ($this->rtl) {
6712: $this->endlinex = $startx - $linew - $shy_width;
6713: } else {
6714: $this->endlinex = $startx + $linew + $shy_width;
6715: }
6716: $w = $linew;
6717: $tmpcellpadding = $this->cell_padding;
6718: if ($maxh == 0) {
6719: $this->SetCellPadding(0);
6720: }
6721: }
6722:
6723: if ($firstblock AND $this->isRTLTextDir()) {
6724: $tmpstr = $this->stringRightTrim($tmpstr);
6725: }
6726: $this->Cell($w, $h, $shy_char_left.$tmpstr.$shy_char_right, 0, 1, $align, $fill, $link, $stretch);
6727: unset($tmpstr);
6728: if ($firstline) {
6729:
6730: $this->cell_padding = $tmpcellpadding;
6731: return ($this->UniArrSubString($uchars, ($sep + $endspace)));
6732: }
6733: $i = $sep;
6734: $sep = -1;
6735: $shy = false;
6736: $j = ($i+1);
6737: }
6738:
6739: if ((($this->y + $this->lasth) > $this->PageBreakTrigger) AND (!$this->InFooter)) {
6740: $this->AcceptPageBreak();
6741: if ($this->rtl) {
6742: $this->x -= $margin['R'];
6743: } else {
6744: $this->x += $margin['L'];
6745: }
6746: $this->lMargin += $margin['L'];
6747: $this->rMargin += $margin['R'];
6748: }
6749: $w = $this->getRemainingWidth();
6750: $wmax = $w - $this->cell_padding['L'] - $this->cell_padding['R'];
6751: if ($linebreak) {
6752: $linebreak = false;
6753: } else {
6754: ++$nl;
6755: $l = 0;
6756: }
6757: }
6758: }
6759:
6760: $pc = $c;
6761: ++$i;
6762: }
6763:
6764: if ($l > 0) {
6765: switch ($align) {
6766: case 'J':
6767: case 'C': {
6768: $w = $w;
6769: break;
6770: }
6771: case 'L': {
6772: if ($this->rtl) {
6773: $w = $w;
6774: } else {
6775: $w = $l;
6776: }
6777: break;
6778: }
6779: case 'R': {
6780: if ($this->rtl) {
6781: $w = $l;
6782: } else {
6783: $w = $w;
6784: }
6785: break;
6786: }
6787: default: {
6788: $w = $l;
6789: break;
6790: }
6791: }
6792: $tmpstr = $this->UniArrSubString($uchars, $j, $nb);
6793: if ($firstline) {
6794: $startx = $this->x;
6795: $tmparr = array_slice($chars, $j, ($nb - $j));
6796: if ($rtlmode) {
6797: $tmparr = $this->utf8Bidi($tmparr, $tmpstr, $this->tmprtl);
6798: }
6799: $linew = $this->GetArrStringWidth($tmparr);
6800: unset($tmparr);
6801: if ($this->rtl) {
6802: $this->endlinex = $startx - $linew;
6803: } else {
6804: $this->endlinex = $startx + $linew;
6805: }
6806: $w = $linew;
6807: $tmpcellpadding = $this->cell_padding;
6808: if ($maxh == 0) {
6809: $this->SetCellPadding(0);
6810: }
6811: }
6812: if ($firstblock AND $this->isRTLTextDir()) {
6813: $tmpstr = $this->stringRightTrim($tmpstr);
6814: }
6815: $this->Cell($w, $h, $tmpstr, 0, $ln, $align, $fill, $link, $stretch);
6816: unset($tmpstr);
6817: if ($firstline) {
6818: $this->cell_padding = $tmpcellpadding;
6819: return ($this->UniArrSubString($uchars, $nb));
6820: }
6821: ++$nl;
6822: }
6823: if ($firstline) {
6824: return '';
6825: }
6826: return $nl;
6827: }
6828:
6829: 6830: 6831: 6832: 6833:
6834: protected function getRemainingWidth() {
6835: $this->checkPageRegions();
6836: if ($this->rtl) {
6837: return ($this->x - $this->lMargin);
6838: } else {
6839: return ($this->w - $this->rMargin - $this->x);
6840: }
6841: }
6842:
6843: 6844: 6845: 6846: 6847: 6848: 6849: 6850:
6851: public function UTF8ArrSubString($strarr, $start='', $end='') {
6852: if (strlen($start) == 0) {
6853: $start = 0;
6854: }
6855: if (strlen($end) == 0) {
6856: $end = count($strarr);
6857: }
6858: $string = '';
6859: for ($i=$start; $i < $end; ++$i) {
6860: $string .= $this->unichr($strarr[$i]);
6861: }
6862: return $string;
6863: }
6864:
6865: 6866: 6867: 6868: 6869: 6870: 6871: 6872: 6873:
6874: public function UniArrSubString($uniarr, $start='', $end='') {
6875: if (strlen($start) == 0) {
6876: $start = 0;
6877: }
6878: if (strlen($end) == 0) {
6879: $end = count($uniarr);
6880: }
6881: $string = '';
6882: for ($i=$start; $i < $end; ++$i) {
6883: $string .= $uniarr[$i];
6884: }
6885: return $string;
6886: }
6887:
6888: 6889: 6890: 6891: 6892: 6893: 6894:
6895: public function UTF8ArrayToUniArray($ta) {
6896: return array_map(array($this, 'unichr'), $ta);
6897: }
6898:
6899: 6900: 6901: 6902: 6903: 6904: 6905: 6906:
6907: public function unichr($c) {
6908: if (!$this->isunicode) {
6909: return chr($c);
6910: } elseif ($c <= 0x7F) {
6911:
6912: return chr($c);
6913: } elseif ($c <= 0x7FF) {
6914:
6915: return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
6916: } elseif ($c <= 0xFFFF) {
6917:
6918: return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
6919: } elseif ($c <= 0x10FFFF) {
6920:
6921: return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
6922: } else {
6923: return '';
6924: }
6925: }
6926:
6927: 6928: 6929: 6930: 6931: 6932: 6933:
6934: public function getImageFileType($imgfile, $iminfo=array()) {
6935: $type = '';
6936: if (isset($iminfo['mime']) AND !empty($iminfo['mime'])) {
6937: $mime = explode('/', $iminfo['mime']);
6938: if ((count($mime) > 1) AND ($mime[0] == 'image') AND (!empty($mime[1]))) {
6939: $type = strtolower(trim($mime[1]));
6940: }
6941: }
6942: if (empty($type)) {
6943: $fileinfo = pathinfo($imgfile);
6944: if (isset($fileinfo['extension']) AND (!$this->empty_string($fileinfo['extension']))) {
6945: $type = strtolower(trim($fileinfo['extension']));
6946: }
6947: }
6948: if ($type == 'jpg') {
6949: $type = 'jpeg';
6950: }
6951: return $type;
6952: }
6953:
6954: 6955: 6956: 6957: 6958: 6959: 6960: 6961: 6962: 6963:
6964: protected function fitBlock(&$w, &$h, &$x, &$y, $fitonpage=false) {
6965:
6966: if ($fitonpage OR $this->AutoPageBreak) {
6967: $ratio_wh = ($w / $h);
6968: if ($h > ($this->PageBreakTrigger - $this->tMargin)) {
6969: $h = $this->PageBreakTrigger - $this->tMargin;
6970: $w = ($h * $ratio_wh);
6971: }
6972:
6973: if ($fitonpage) {
6974: $maxw = ($this->w - $this->lMargin - $this->rMargin);
6975: if ($w > $maxw) {
6976: $w = $maxw;
6977: $h = ($w / $ratio_wh);
6978: }
6979: }
6980: }
6981:
6982: $prev_x = $this->x;
6983: $prev_y = $this->y;
6984: if ($this->checkPageBreak($h, $y) OR ($this->y < $prev_y)) {
6985: $y = $this->y;
6986: if ($this->rtl) {
6987: $x += ($prev_x - $this->x);
6988: } else {
6989: $x += ($this->x - $prev_x);
6990: }
6991: }
6992:
6993: if ($fitonpage) {
6994: $ratio_wh = ($w / $h);
6995: if (($y + $h) > $this->PageBreakTrigger) {
6996: $h = $this->PageBreakTrigger - $y;
6997: $w = ($h * $ratio_wh);
6998: }
6999: if ((!$this->rtl) AND (($x + $w) > ($this->w - $this->rMargin))) {
7000: $w = $this->w - $this->rMargin - $x;
7001: $h = ($w / $ratio_wh);
7002: } elseif (($this->rtl) AND (($x - $w) < ($this->lMargin))) {
7003: $w = $x - $this->lMargin;
7004: $h = ($w / $ratio_wh);
7005: }
7006: }
7007: }
7008:
7009: 7010: 7011: 7012: 7013: 7014: 7015: 7016: 7017: 7018: 7019: 7020: 7021: 7022: 7023: 7024: 7025: 7026: 7027: 7028: 7029: 7030: 7031: 7032: 7033: 7034: 7035: 7036: 7037: 7038: 7039: 7040:
7041: public function Image($file, $x='', $y='', $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0, $fitbox=false, $hidden=false, $fitonpage=false) {
7042: if ($x === '') {
7043: $x = $this->x;
7044: }
7045: if ($y === '') {
7046: $y = $this->y;
7047: }
7048:
7049: $this->checkPageRegions($h, $x, $y);
7050: $cached_file = false;
7051:
7052: $imsize = @getimagesize($file);
7053: if ($imsize === FALSE) {
7054:
7055: $file = str_replace(' ', '%20', $file);
7056: $imsize = @getimagesize($file);
7057: if ($imsize === FALSE) {
7058: if (function_exists('curl_init')) {
7059:
7060: $cs = curl_init();
7061: curl_setopt($cs, CURLOPT_URL, $file);
7062: curl_setopt($cs, CURLOPT_BINARYTRANSFER, true);
7063: curl_setopt($cs, CURLOPT_FAILONERROR, true);
7064: curl_setopt($cs, CURLOPT_RETURNTRANSFER, true);
7065: curl_setopt($cs, CURLOPT_CONNECTTIMEOUT, 5);
7066: curl_setopt($cs, CURLOPT_TIMEOUT, 30);
7067: $imgdata = curl_exec($cs);
7068: curl_close($cs);
7069: if($imgdata !== FALSE) {
7070:
7071: $file = tempnam(K_PATH_CACHE, 'img_');
7072: $fp = fopen($file, 'w');
7073: fwrite($fp, $imgdata);
7074: fclose($fp);
7075: unset($imgdata);
7076: $cached_file = true;
7077: $imsize = @getimagesize($file);
7078: if ($imsize === FALSE) {
7079: unlink($file);
7080: $cached_file = false;
7081: }
7082: }
7083: } elseif (($w > 0) AND ($h > 0)) {
7084:
7085: $pw = $this->getHTMLUnitToUnits($w, 0, $this->pdfunit, true) * $this->imgscale * $this->k;
7086: $ph = $this->getHTMLUnitToUnits($h, 0, $this->pdfunit, true) * $this->imgscale * $this->k;
7087: $imsize = array($pw, $ph);
7088: }
7089: }
7090: }
7091: if ($imsize === FALSE) {
7092: $this->Error('[Image] Unable to get image: '.$file);
7093: }
7094:
7095: list($pixw, $pixh) = $imsize;
7096:
7097: if (($w <= 0) AND ($h <= 0)) {
7098:
7099: $w = $this->pixelsToUnits($pixw);
7100: $h = $this->pixelsToUnits($pixh);
7101: } elseif ($w <= 0) {
7102: $w = $h * $pixw / $pixh;
7103: } elseif ($h <= 0) {
7104: $h = $w * $pixh / $pixw;
7105: } elseif ($fitbox AND ($w > 0) AND ($h > 0)) {
7106:
7107: if ((($w * $pixh) / ($h * $pixw)) < 1) {
7108: $h = $w * $pixh / $pixw;
7109: } else {
7110: $w = $h * $pixw / $pixh;
7111: }
7112: }
7113:
7114: $this->fitBlock($w, $h, $x, $y, $fitonpage);
7115:
7116: $neww = round($w * $this->k * $dpi / $this->dpi);
7117: $newh = round($h * $this->k * $dpi / $this->dpi);
7118:
7119: $newsize = ($neww * $newh);
7120: $pixsize = ($pixw * $pixh);
7121: if (intval($resize) == 2) {
7122: $resize = true;
7123: } elseif ($newsize >= $pixsize) {
7124: $resize = false;
7125: }
7126:
7127: $newimage = true;
7128: if (in_array($file, $this->imagekeys)) {
7129: $newimage = false;
7130:
7131: $info = $this->getImageBuffer($file);
7132:
7133: $oldsize = ($info['w'] * $info['h']);
7134: if ((($oldsize < $newsize) AND ($resize)) OR (($oldsize < $pixsize) AND (!$resize))) {
7135: $newimage = true;
7136: }
7137: }
7138: if ($newimage) {
7139:
7140: $type = strtolower($type);
7141: if ($type == '') {
7142: $type = $this->getImageFileType($file, $imsize);
7143: } elseif ($type == 'jpg') {
7144: $type = 'jpeg';
7145: }
7146: $mqr = $this->get_mqr();
7147: $this->set_mqr(false);
7148:
7149: $mtd = '_parse'.$type;
7150:
7151: $gdfunction = 'imagecreatefrom'.$type;
7152: $info = false;
7153: if ((method_exists($this, $mtd)) AND (!($resize AND function_exists($gdfunction)))) {
7154:
7155: $info = $this->$mtd($file);
7156: if ($info == 'pngalpha') {
7157: return $this->ImagePngAlpha($file, $x, $y, $pixw, $pixh, $w, $h, 'PNG', $link, $align, $resize, $dpi, $palign);
7158: }
7159: }
7160: if (!$info) {
7161: if (function_exists($gdfunction)) {
7162:
7163: $img = $gdfunction($file);
7164: if ($resize) {
7165: $imgr = imagecreatetruecolor($neww, $newh);
7166: if (($type == 'gif') OR ($type == 'png')) {
7167: $imgr = $this->_setGDImageTransparency($imgr, $img);
7168: }
7169: imagecopyresampled($imgr, $img, 0, 0, 0, 0, $neww, $newh, $pixw, $pixh);
7170: if (($type == 'gif') OR ($type == 'png')) {
7171: $info = $this->_toPNG($imgr);
7172: } else {
7173: $info = $this->_toJPEG($imgr);
7174: }
7175: } else {
7176: if (($type == 'gif') OR ($type == 'png')) {
7177: $info = $this->_toPNG($img);
7178: } else {
7179: $info = $this->_toJPEG($img);
7180: }
7181: }
7182: } elseif (extension_loaded('imagick')) {
7183:
7184: $img = new Imagick();
7185: if ($type == 'SVG') {
7186:
7187: $svgimg = file_get_contents($file);
7188:
7189: $regs = array();
7190: if (preg_match('/<svg([^\>]*)>/si', $svgimg, $regs)) {
7191: $svgtag = $regs[1];
7192: $tmp = array();
7193: if (preg_match('/[\s]+width[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) {
7194: $ow = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false);
7195: $owu = sprintf('%.3F', ($ow * $dpi / 72)).$this->pdfunit;
7196: $svgtag = preg_replace('/[\s]+width[\s]*=[\s]*"[^"]*"/si', ' width="'.$owu.'"', $svgtag, 1);
7197: } else {
7198: $ow = $w;
7199: }
7200: $tmp = array();
7201: if (preg_match('/[\s]+height[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) {
7202: $oh = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false);
7203: $ohu = sprintf('%.3F', ($oh * $dpi / 72)).$this->pdfunit;
7204: $svgtag = preg_replace('/[\s]+height[\s]*=[\s]*"[^"]*"/si', ' height="'.$ohu.'"', $svgtag, 1);
7205: } else {
7206: $oh = $h;
7207: }
7208: $tmp = array();
7209: if (!preg_match('/[\s]+viewBox[\s]*=[\s]*"[\s]*([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]*"/si', $svgtag, $tmp)) {
7210: $vbw = ($ow * $this->imgscale * $this->k);
7211: $vbh = ($oh * $this->imgscale * $this->k);
7212: $vbox = sprintf(' viewBox="0 0 %.3F %.3F" ', $vbw, $vbh);
7213: $svgtag = $vbox.$svgtag;
7214: }
7215: $svgimg = preg_replace('/<svg([^\>]*)>/si', '<svg'.$svgtag.'>', $svgimg, 1);
7216: }
7217: $img->readImageBlob($svgimg);
7218: } else {
7219: $img->readImage($file);
7220: }
7221: if ($resize) {
7222: $img->resizeImage($neww, $newh, 10, 1, false);
7223: }
7224: $img->setCompressionQuality($this->jpeg_quality);
7225: $img->setImageFormat('jpeg');
7226: $tempname = tempnam(K_PATH_CACHE, 'jpg_');
7227: $img->writeImage($tempname);
7228: $info = $this->_parsejpeg($tempname);
7229: unlink($tempname);
7230: $img->destroy();
7231: } else {
7232: return;
7233: }
7234: }
7235: if ($info === false) {
7236:
7237: return;
7238: }
7239: $this->set_mqr($mqr);
7240: if ($ismask) {
7241:
7242: $info['cs'] = 'DeviceGray';
7243: }
7244: $info['i'] = $this->numimages;
7245: if (!in_array($file, $this->imagekeys)) {
7246: ++$info['i'];
7247: }
7248: if ($imgmask !== false) {
7249: $info['masked'] = $imgmask;
7250: }
7251:
7252: $this->setImageBuffer($file, $info);
7253: }
7254: if ($cached_file) {
7255:
7256: unlink($file);
7257: }
7258:
7259: $this->img_rb_y = $y + $h;
7260:
7261: if ($this->rtl) {
7262: if ($palign == 'L') {
7263: $ximg = $this->lMargin;
7264: } elseif ($palign == 'C') {
7265: $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
7266: } elseif ($palign == 'R') {
7267: $ximg = $this->w - $this->rMargin - $w;
7268: } else {
7269: $ximg = $x - $w;
7270: }
7271: $this->img_rb_x = $ximg;
7272: } else {
7273: if ($palign == 'L') {
7274: $ximg = $this->lMargin;
7275: } elseif ($palign == 'C') {
7276: $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
7277: } elseif ($palign == 'R') {
7278: $ximg = $this->w - $this->rMargin - $w;
7279: } else {
7280: $ximg = $x;
7281: }
7282: $this->img_rb_x = $ximg + $w;
7283: }
7284: if ($ismask OR $hidden) {
7285:
7286: return $info['i'];
7287: }
7288: $xkimg = $ximg * $this->k;
7289: $this->_out(sprintf('q %.2F 0 0 %.2F %.2F %.2F cm /I%u Do Q', ($w * $this->k), ($h * $this->k), $xkimg, (($this->h - ($y + $h)) * $this->k), $info['i']));
7290: if (!empty($border)) {
7291: $bx = $this->x;
7292: $by = $this->y;
7293: $this->x = $ximg;
7294: if ($this->rtl) {
7295: $this->x += $w;
7296: }
7297: $this->y = $y;
7298: $this->Cell($w, $h, '', $border, 0, '', 0, '', 0, true);
7299: $this->x = $bx;
7300: $this->y = $by;
7301: }
7302: if ($link) {
7303: $this->Link($ximg, $y, $w, $h, $link, 0);
7304: }
7305:
7306: switch($align) {
7307: case 'T': {
7308: $this->y = $y;
7309: $this->x = $this->img_rb_x;
7310: break;
7311: }
7312: case 'M': {
7313: $this->y = $y + round($h/2);
7314: $this->x = $this->img_rb_x;
7315: break;
7316: }
7317: case 'B': {
7318: $this->y = $this->img_rb_y;
7319: $this->x = $this->img_rb_x;
7320: break;
7321: }
7322: case 'N': {
7323: $this->SetY($this->img_rb_y);
7324: break;
7325: }
7326: default:{
7327: break;
7328: }
7329: }
7330: $this->endlinex = $this->img_rb_x;
7331: if ($this->inxobj) {
7332:
7333: $this->xobjects[$this->xobjid]['images'][] = $info['i'];
7334: }
7335: return $info['i'];
7336: }
7337:
7338: 7339: 7340: 7341: 7342:
7343: public function set_mqr($mqr) {
7344: if(!defined('PHP_VERSION_ID')) {
7345: $version = PHP_VERSION;
7346: define('PHP_VERSION_ID', (($version{0} * 10000) + ($version{2} * 100) + $version{4}));
7347: }
7348: if (PHP_VERSION_ID < 50300) {
7349: @set_magic_quotes_runtime($mqr);
7350: }
7351: }
7352:
7353: 7354: 7355: 7356: 7357:
7358: public function get_mqr() {
7359: if(!defined('PHP_VERSION_ID')) {
7360: $version = PHP_VERSION;
7361: define('PHP_VERSION_ID', (($version{0} * 10000) + ($version{2} * 100) + $version{4}));
7362: }
7363: if (PHP_VERSION_ID < 50300) {
7364: return @get_magic_quotes_runtime();
7365: }
7366: return 0;
7367: }
7368:
7369: 7370: 7371: 7372: 7373: 7374: 7375: 7376:
7377: protected function _toJPEG($image) {
7378: $tempname = tempnam(K_PATH_CACHE, 'jpg_');
7379: imagejpeg($image, $tempname, $this->jpeg_quality);
7380: imagedestroy($image);
7381: $retvars = $this->_parsejpeg($tempname);
7382:
7383: unlink($tempname);
7384: return $retvars;
7385: }
7386:
7387: 7388: 7389: 7390: 7391: 7392: 7393: 7394: 7395:
7396: protected function _toPNG($image) {
7397: $tempname = tempnam(K_PATH_CACHE, 'jpg_');
7398: imagepng($image, $tempname);
7399: imagedestroy($image);
7400: $retvars = $this->_parsepng($tempname);
7401:
7402: unlink($tempname);
7403: return $retvars;
7404: }
7405:
7406: 7407: 7408: 7409: 7410: 7411: 7412: 7413:
7414: protected function _setGDImageTransparency($new_image, $image) {
7415:
7416: $tid = imagecolortransparent($image);
7417:
7418: $tcol = array('red' => 255, 'green' => 255, 'blue' => 255);
7419: if ($tid >= 0) {
7420:
7421: $tcol = imagecolorsforindex($image, $tid);
7422: }
7423: $tid = imagecolorallocate($new_image, $tcol['red'], $tcol['green'], $tcol['blue']);
7424: imagefill($new_image, 0, 0, $tid);
7425: imagecolortransparent($new_image, $tid);
7426: return $new_image;
7427: }
7428:
7429: 7430: 7431: 7432: 7433: 7434:
7435: protected function _parsejpeg($file) {
7436: $a = getimagesize($file);
7437: if (empty($a)) {
7438: $this->Error('Missing or incorrect image file: '.$file);
7439: }
7440: if ($a[2] != 2) {
7441: $this->Error('Not a JPEG file: '.$file);
7442: }
7443: if ((!isset($a['channels'])) OR ($a['channels'] == 3)) {
7444: $colspace = 'DeviceRGB';
7445: } elseif ($a['channels'] == 4) {
7446: $colspace = 'DeviceCMYK';
7447: } else {
7448: $colspace = 'DeviceGray';
7449: }
7450: $bpc = isset($a['bits']) ? $a['bits'] : 8;
7451: $data = file_get_contents($file);
7452: return array('w' => $a[0], 'h' => $a[1], 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'DCTDecode', 'data' => $data);
7453: }
7454:
7455: 7456: 7457: 7458: 7459: 7460:
7461: protected function _parsepng($file) {
7462: $f = fopen($file, 'rb');
7463: if ($f === false) {
7464: $this->Error('Can\'t open image file: '.$file);
7465: }
7466:
7467: if (fread($f, 8) != chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) {
7468: $this->Error('Not a PNG file: '.$file);
7469: }
7470:
7471: fread($f, 4);
7472: if (fread($f, 4) != 'IHDR') {
7473: $this->Error('Incorrect PNG file: '.$file);
7474: }
7475: $w = $this->_freadint($f);
7476: $h = $this->_freadint($f);
7477: $bpc = ord(fread($f, 1));
7478: if ($bpc > 8) {
7479:
7480: fclose($f);
7481: return false;
7482: }
7483: $ct = ord(fread($f, 1));
7484: if ($ct == 0) {
7485: $colspace = 'DeviceGray';
7486: } elseif ($ct == 2) {
7487: $colspace = 'DeviceRGB';
7488: } elseif ($ct == 3) {
7489: $colspace = 'Indexed';
7490: } else {
7491:
7492: fclose($f);
7493: return 'pngalpha';
7494: }
7495: if (ord(fread($f, 1)) != 0) {
7496:
7497: fclose($f);
7498: return false;
7499: }
7500: if (ord(fread($f, 1)) != 0) {
7501:
7502: fclose($f);
7503: return false;
7504: }
7505: if (ord(fread($f, 1)) != 0) {
7506:
7507: fclose($f);
7508: return false;
7509: }
7510: fread($f, 4);
7511: $parms = '/DecodeParms << /Predictor 15 /Colors '.($ct == 2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.' >>';
7512:
7513: $pal = '';
7514: $trns = '';
7515: $data = '';
7516: do {
7517: $n = $this->_freadint($f);
7518: $type = fread($f, 4);
7519: if ($type == 'PLTE') {
7520:
7521: $pal = $this->rfread($f, $n);
7522: fread($f, 4);
7523: } elseif ($type == 'tRNS') {
7524:
7525: $t = $this->rfread($f, $n);
7526: if ($ct == 0) {
7527: $trns = array(ord(substr($t, 1, 1)));
7528: } elseif ($ct == 2) {
7529: $trns = array(ord(substr($t, 1, 1)), ord(substr($t, 3, 1)), ord(substr($t, 5, 1)));
7530: } else {
7531: $pos = strpos($t, chr(0));
7532: if ($pos !== false) {
7533: $trns = array($pos);
7534: }
7535: }
7536: fread($f, 4);
7537: } elseif ($type == 'IDAT') {
7538:
7539: $data .= $this->rfread($f, $n);
7540: fread($f, 4);
7541: } elseif ($type == 'IEND') {
7542: break;
7543: } else {
7544: $this->rfread($f, $n + 4);
7545: }
7546: } while ($n);
7547: if (($colspace == 'Indexed') AND (empty($pal))) {
7548:
7549: fclose($f);
7550: return false;
7551: }
7552: fclose($f);
7553: return array('w' => $w, 'h' => $h, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'FlateDecode', 'parms' => $parms, 'pal' => $pal, 'trns' => $trns, 'data' => $data);
7554: }
7555:
7556: 7557: 7558: 7559: 7560: 7561: 7562: 7563: 7564: 7565:
7566: protected function rfread($handle, $length) {
7567: $data = fread($handle, $length);
7568: if ($data === false) {
7569: return false;
7570: }
7571: $rest = $length - strlen($data);
7572: if ($rest > 0) {
7573: $data .= $this->rfread($handle, $rest);
7574: }
7575: return $data;
7576: }
7577:
7578: 7579: 7580: 7581: 7582: 7583: 7584: 7585: 7586: 7587: 7588: 7589: 7590: 7591: 7592: 7593: 7594: 7595: 7596: 7597:
7598: protected function ImagePngAlpha($file, $x, $y, $wpx, $hpx, $w, $h, $type, $link, $align, $resize, $dpi, $palign) {
7599:
7600: $tempfile_plain = tempnam(K_PATH_CACHE, 'mskp_');
7601:
7602: $tempfile_alpha = tempnam(K_PATH_CACHE, 'mska_');
7603: if (extension_loaded('imagick')) {
7604:
7605: $img = new Imagick();
7606: $img->readImage($file);
7607:
7608: $imga = $img->clone();
7609:
7610: $img->separateImageChannel(imagick::CHANNEL_ALPHA | imagick::CHANNEL_OPACITY | imagick::CHANNEL_MATTE);
7611: $img->negateImage(true);
7612: $img->setImageFormat('png');
7613: $img->writeImage($tempfile_alpha);
7614:
7615: $imga->separateImageChannel(imagick::CHANNEL_ALL & ~(imagick::CHANNEL_ALPHA | imagick::CHANNEL_OPACITY | imagick::CHANNEL_MATTE));
7616: $imga->setImageFormat('png');
7617: $imga->writeImage($tempfile_plain);
7618: } else {
7619:
7620: $img = imagecreatefrompng($file);
7621: $imgalpha = imagecreate($wpx, $hpx);
7622:
7623: for ($c = 0; $c < 256; ++$c) {
7624: ImageColorAllocate($imgalpha, $c, $c, $c);
7625: }
7626:
7627: for ($xpx = 0; $xpx < $wpx; ++$xpx) {
7628: for ($ypx = 0; $ypx < $hpx; ++$ypx) {
7629: $color = imagecolorat($img, $xpx, $ypx);
7630: $alpha = ($color >> 24);
7631: $alpha = (((127 - $alpha) / 127) * 255);
7632: $alpha = $this->getGDgamma($alpha);
7633: imagesetpixel($imgalpha, $xpx, $ypx, $alpha);
7634: }
7635: }
7636: imagepng($imgalpha, $tempfile_alpha);
7637: imagedestroy($imgalpha);
7638:
7639: $imgplain = imagecreatetruecolor($wpx, $hpx);
7640: imagecopy($imgplain, $img, 0, 0, 0, 0, $wpx, $hpx);
7641: imagepng($imgplain, $tempfile_plain);
7642: imagedestroy($imgplain);
7643: }
7644:
7645: $imgmask = $this->Image($tempfile_alpha, $x, $y, $w, $h, 'PNG', '', '', $resize, $dpi, '', true, false);
7646:
7647: $this->Image($tempfile_plain, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, false, $imgmask);
7648:
7649: unlink($tempfile_alpha);
7650: unlink($tempfile_plain);
7651: }
7652:
7653: 7654: 7655: 7656: 7657: 7658:
7659: protected function getGDgamma($v) {
7660: return (pow(($v / 255), 2.2) * 255);
7661: }
7662:
7663: 7664: 7665: 7666: 7667: 7668: 7669: 7670: 7671:
7672: public function Ln($h='', $cell=false) {
7673: if (($this->num_columns > 1) AND ($this->y == $this->columns[$this->current_column]['y']) AND isset($this->columns[$this->current_column]['x']) AND ($this->x == $this->columns[$this->current_column]['x'])) {
7674:
7675: return;
7676: }
7677: if ($cell) {
7678: if ($this->rtl) {
7679: $cellpadding = $this->cell_padding['R'];
7680: } else {
7681: $cellpadding = $this->cell_padding['L'];
7682: }
7683: } else {
7684: $cellpadding = 0;
7685: }
7686: if ($this->rtl) {
7687: $this->x = $this->w - $this->rMargin - $cellpadding;
7688: } else {
7689: $this->x = $this->lMargin + $cellpadding;
7690: }
7691: if (is_string($h)) {
7692: $this->y += $this->lasth;
7693: } else {
7694: $this->y += $h;
7695: }
7696: $this->newline = true;
7697: }
7698:
7699: 7700: 7701: 7702: 7703: 7704: 7705: 7706:
7707: public function GetX() {
7708:
7709: if ($this->rtl) {
7710: return ($this->w - $this->x);
7711: } else {
7712: return $this->x;
7713: }
7714: }
7715:
7716: 7717: 7718: 7719: 7720: 7721: 7722:
7723: public function GetAbsX() {
7724: return $this->x;
7725: }
7726:
7727: 7728: 7729: 7730: 7731: 7732: 7733:
7734: public function GetY() {
7735: return $this->y;
7736: }
7737:
7738: 7739: 7740: 7741: 7742: 7743: 7744: 7745: 7746:
7747: public function SetX($x, $rtloff=false) {
7748: if (!$rtloff AND $this->rtl) {
7749: if ($x >= 0) {
7750: $this->x = $this->w - $x;
7751: } else {
7752: $this->x = abs($x);
7753: }
7754: } else {
7755: if ($x >= 0) {
7756: $this->x = $x;
7757: } else {
7758: $this->x = $this->w + $x;
7759: }
7760: }
7761: if ($this->x < 0) {
7762: $this->x = 0;
7763: }
7764: if ($this->x > $this->w) {
7765: $this->x = $this->w;
7766: }
7767: }
7768:
7769: 7770: 7771: 7772: 7773: 7774: 7775: 7776: 7777: 7778:
7779: public function SetY($y, $resetx=true, $rtloff=false) {
7780: if ($resetx) {
7781:
7782: if (!$rtloff AND $this->rtl) {
7783: $this->x = $this->w - $this->rMargin;
7784: } else {
7785: $this->x = $this->lMargin;
7786: }
7787: }
7788: if ($y >= 0) {
7789: $this->y = $y;
7790: } else {
7791: $this->y = $this->h + $y;
7792: }
7793: if ($this->y < 0) {
7794: $this->y = 0;
7795: }
7796: if ($this->y > $this->h) {
7797: $this->y = $this->h;
7798: }
7799: }
7800:
7801: 7802: 7803: 7804: 7805: 7806: 7807: 7808: 7809: 7810:
7811: public function SetXY($x, $y, $rtloff=false) {
7812: $this->SetY($y, false, $rtloff);
7813: $this->SetX($x, $rtloff);
7814: }
7815:
7816: 7817: 7818: 7819: 7820: 7821: 7822: 7823: 7824: 7825:
7826: public function Output($name='doc.pdf', $dest='I') {
7827:
7828:
7829: if ($this->state < 3) {
7830: $this->Close();
7831: }
7832:
7833: if (is_bool($dest)) {
7834: $dest = $dest ? 'D' : 'F';
7835: }
7836: $dest = strtoupper($dest);
7837: if ($dest{0} != 'F') {
7838: $name = preg_replace('/[\s]+/', '_', $name);
7839: $name = preg_replace('/[^a-zA-Z0-9_\.-]/', '', $name);
7840: }
7841: if ($this->sign) {
7842:
7843:
7844: $pdfdoc = $this->getBuffer();
7845:
7846: $pdfdoc = substr($pdfdoc, 0, -1);
7847:
7848: if (isset($this->diskcache) AND $this->diskcache) {
7849:
7850: unlink($this->buffer);
7851: }
7852: unset($this->buffer);
7853:
7854: $byterange_string_len = strlen($this->byterange_string);
7855:
7856: $byte_range = array();
7857: $byte_range[0] = 0;
7858: $byte_range[1] = strpos($pdfdoc, $this->byterange_string) + $byterange_string_len + 10;
7859: $byte_range[2] = $byte_range[1] + $this->signature_max_length + 2;
7860: $byte_range[3] = strlen($pdfdoc) - $byte_range[2];
7861: $pdfdoc = substr($pdfdoc, 0, $byte_range[1]).substr($pdfdoc, $byte_range[2]);
7862:
7863: $byterange = sprintf('/ByteRange[0 %u %u %u]', $byte_range[1], $byte_range[2], $byte_range[3]);
7864: $byterange .= str_repeat(' ', ($byterange_string_len - strlen($byterange)));
7865: $pdfdoc = str_replace($this->byterange_string, $byterange, $pdfdoc);
7866:
7867: $tempdoc = tempnam(K_PATH_CACHE, 'tmppdf_');
7868: $f = fopen($tempdoc, 'wb');
7869: if (!$f) {
7870: $this->Error('Unable to create temporary file: '.$tempdoc);
7871: }
7872: $pdfdoc_length = strlen($pdfdoc);
7873: fwrite($f, $pdfdoc, $pdfdoc_length);
7874: fclose($f);
7875:
7876: $tempsign = tempnam(K_PATH_CACHE, 'tmpsig_');
7877: if (empty($this->signature_data['extracerts'])) {
7878: openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED);
7879: } else {
7880: openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED, $this->signature_data['extracerts']);
7881: }
7882: unlink($tempdoc);
7883:
7884: $signature = file_get_contents($tempsign);
7885: unlink($tempsign);
7886:
7887: $signature = substr($signature, $pdfdoc_length);
7888: $signature = substr($signature, (strpos($signature, "%%EOF\n\n------") + 13));
7889: $tmparr = explode("\n\n", $signature);
7890: $signature = $tmparr[1];
7891: unset($tmparr);
7892:
7893: $signature = base64_decode(trim($signature));
7894:
7895: $signature = current(unpack('H*', $signature));
7896: $signature = str_pad($signature, $this->signature_max_length, '0');
7897:
7898: $pdfdoc = substr($pdfdoc, 0, $byte_range[1]).'<'.$signature.'>'.substr($pdfdoc, $byte_range[1]);
7899: $this->diskcache = false;
7900: $this->buffer = &$pdfdoc;
7901: $this->bufferlen = strlen($pdfdoc);
7902: }
7903: switch($dest) {
7904: case 'I': {
7905:
7906: if (ob_get_contents()) {
7907: $this->Error('Some data has already been output, can\'t send PDF file');
7908: }
7909: if (php_sapi_name() != 'cli') {
7910:
7911: header('Content-Type: application/pdf');
7912: if (headers_sent()) {
7913: $this->Error('Some data has already been output to browser, can\'t send PDF file');
7914: }
7915: header('Cache-Control: public, must-revalidate, max-age=0');
7916: header('Pragma: public');
7917: header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7918: header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7919: header('Content-Length: '.$this->bufferlen);
7920: header('Content-Disposition: inline; filename="'.basename($name).'";');
7921: }
7922: echo $this->getBuffer();
7923: break;
7924: }
7925: case 'D': {
7926:
7927: if (ob_get_contents()) {
7928: $this->Error('Some data has already been output, can\'t send PDF file');
7929: }
7930: header('Content-Description: File Transfer');
7931: if (headers_sent()) {
7932: $this->Error('Some data has already been output to browser, can\'t send PDF file');
7933: }
7934: header('Cache-Control: public, must-revalidate, max-age=0');
7935: header('Pragma: public');
7936: header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7937: header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7938:
7939: header('Content-Type: application/force-download');
7940: header('Content-Type: application/octet-stream', false);
7941: header('Content-Type: application/download', false);
7942: header('Content-Type: application/pdf', false);
7943:
7944: header('Content-Disposition: attachment; filename="'.basename($name).'";');
7945: header('Content-Transfer-Encoding: binary');
7946: header('Content-Length: '.$this->bufferlen);
7947: echo $this->getBuffer();
7948: break;
7949: }
7950: case 'F':
7951: case 'FI':
7952: case 'FD': {
7953:
7954: if ($this->diskcache) {
7955: copy($this->buffer, $name);
7956: } else {
7957: $f = fopen($name, 'wb');
7958: if (!$f) {
7959: $this->Error('Unable to create output file: '.$name);
7960: }
7961: fwrite($f, $this->getBuffer(), $this->bufferlen);
7962: fclose($f);
7963: }
7964: if ($dest == 'FI') {
7965:
7966: header('Content-Type: application/pdf');
7967: header('Cache-Control: public, must-revalidate, max-age=0');
7968: header('Pragma: public');
7969: header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7970: header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7971: header('Content-Length: '.filesize($name));
7972: header('Content-Disposition: inline; filename="'.basename($name).'";');
7973:
7974: echo file_get_contents($name);
7975: } elseif ($dest == 'FD') {
7976:
7977: if (ob_get_contents()) {
7978: $this->Error('Some data has already been output, can\'t send PDF file');
7979: }
7980: header('Content-Description: File Transfer');
7981: if (headers_sent()) {
7982: $this->Error('Some data has already been output to browser, can\'t send PDF file');
7983: }
7984: header('Cache-Control: public, must-revalidate, max-age=0');
7985: header('Pragma: public');
7986: header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
7987: header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
7988:
7989: header('Content-Type: application/force-download');
7990: header('Content-Type: application/octet-stream', false);
7991: header('Content-Type: application/download', false);
7992: header('Content-Type: application/pdf', false);
7993:
7994: header('Content-Disposition: attachment; filename="'.basename($name).'";');
7995: header('Content-Transfer-Encoding: binary');
7996: header('Content-Length: '.filesize($name));
7997:
7998: echo file_get_contents($name);
7999: }
8000: break;
8001: }
8002: case 'S': {
8003:
8004: return $this->getBuffer();
8005: }
8006: default: {
8007: $this->Error('Incorrect output destination: '.$dest);
8008: }
8009: }
8010: return '';
8011: }
8012:
8013: 8014: 8015: 8016: 8017: 8018: 8019:
8020: public function _destroy($destroyall=false, $preserve_objcopy=false) {
8021: if ($destroyall AND isset($this->diskcache) AND $this->diskcache AND (!$preserve_objcopy) AND (!$this->empty_string($this->buffer))) {
8022:
8023: unlink($this->buffer);
8024: }
8025: foreach (array_keys(get_object_vars($this)) as $val) {
8026: if ($destroyall OR (
8027: ($val != 'internal_encoding')
8028: AND ($val != 'state')
8029: AND ($val != 'bufferlen')
8030: AND ($val != 'buffer')
8031: AND ($val != 'diskcache')
8032: AND ($val != 'sign')
8033: AND ($val != 'signature_data')
8034: AND ($val != 'signature_max_length')
8035: AND ($val != 'byterange_string')
8036: )) {
8037: if ((!$preserve_objcopy OR ($val != 'objcopy')) AND isset($this->$val)) {
8038: unset($this->$val);
8039: }
8040: }
8041: }
8042: }
8043:
8044: 8045: 8046: 8047:
8048: protected function _dochecks() {
8049:
8050: if (1.1 == 1) {
8051: $this->Error('Don\'t alter the locale before including class file');
8052: }
8053:
8054: if (sprintf('%.1F', 1.0) != '1.0') {
8055: setlocale(LC_NUMERIC, 'C');
8056: }
8057: }
8058:
8059: 8060: 8061: 8062: 8063:
8064: protected function _getfontpath() {
8065: if (!defined('K_PATH_FONTS') AND is_dir(dirname(__FILE__).'/fonts')) {
8066: define('K_PATH_FONTS', dirname(__FILE__).'/fonts/');
8067: }
8068: return defined('K_PATH_FONTS') ? K_PATH_FONTS : '';
8069: }
8070:
8071: 8072: 8073: 8074:
8075: protected function _putpages() {
8076: $nb = $this->numpages;
8077: if (!empty($this->AliasNbPages)) {
8078: $nbs = $this->formatPageNumber($nb);
8079: $nbu = $this->UTF8ToUTF16BE($nbs, false);
8080: $alias_a = $this->_escape($this->AliasNbPages);
8081: $alias_au = $this->_escape('{'.$this->AliasNbPages.'}');
8082: if ($this->isunicode) {
8083: $alias_b = $this->_escape($this->UTF8ToLatin1($this->AliasNbPages));
8084: $alias_bu = $this->_escape($this->UTF8ToLatin1('{'.$this->AliasNbPages.'}'));
8085: $alias_c = $this->_escape($this->utf8StrRev($this->AliasNbPages, false, $this->tmprtl));
8086: $alias_cu = $this->_escape($this->utf8StrRev('{'.$this->AliasNbPages.'}', false, $this->tmprtl));
8087: }
8088: }
8089: if (!empty($this->AliasNumPage)) {
8090: $alias_pa = $this->_escape($this->AliasNumPage);
8091: $alias_pau = $this->_escape('{'.$this->AliasNumPage.'}');
8092: if ($this->isunicode) {
8093: $alias_pb = $this->_escape($this->UTF8ToLatin1($this->AliasNumPage));
8094: $alias_pbu = $this->_escape($this->UTF8ToLatin1('{'.$this->AliasNumPage.'}'));
8095: $alias_pc = $this->_escape($this->utf8StrRev($this->AliasNumPage, false, $this->tmprtl));
8096: $alias_pcu = $this->_escape($this->utf8StrRev('{'.$this->AliasNumPage.'}', false, $this->tmprtl));
8097: }
8098: }
8099: $pagegroupnum = 0;
8100: $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
8101: for ($n=1; $n <= $nb; ++$n) {
8102: $temppage = $this->getPageBuffer($n);
8103: if (!empty($this->pagegroups)) {
8104: if(isset($this->newpagegroup[$n])) {
8105: $pagegroupnum = 0;
8106: }
8107: ++$pagegroupnum;
8108: foreach ($this->pagegroups as $k => $v) {
8109:
8110: $vs = $this->formatPageNumber($v);
8111: $vu = $this->UTF8ToUTF16BE($vs, false);
8112: $alias_ga = $this->_escape($k);
8113: $alias_gau = $this->_escape('{'.$k.'}');
8114: if ($this->isunicode) {
8115: $alias_gb = $this->_escape($this->UTF8ToLatin1($k));
8116: $alias_gbu = $this->_escape($this->UTF8ToLatin1('{'.$k.'}'));
8117: $alias_gc = $this->_escape($this->utf8StrRev($k, false, $this->tmprtl));
8118: $alias_gcu = $this->_escape($this->utf8StrRev('{'.$k.'}', false, $this->tmprtl));
8119: }
8120: $temppage = str_replace($alias_gau, $vu, $temppage);
8121: if ($this->isunicode) {
8122: $temppage = str_replace($alias_gbu, $vu, $temppage);
8123: $temppage = str_replace($alias_gcu, $vu, $temppage);
8124: $temppage = str_replace($alias_gb, $vs, $temppage);
8125: $temppage = str_replace($alias_gc, $vs, $temppage);
8126: }
8127: $temppage = str_replace($alias_ga, $vs, $temppage);
8128:
8129: $pvs = $this->formatPageNumber($pagegroupnum);
8130: $pvu = $this->UTF8ToUTF16BE($pvs, false);
8131: $pk = str_replace('{nb', '{pnb', $k);
8132: $alias_pga = $this->_escape($pk);
8133: $alias_pgau = $this->_escape('{'.$pk.'}');
8134: if ($this->isunicode) {
8135: $alias_pgb = $this->_escape($this->UTF8ToLatin1($pk));
8136: $alias_pgbu = $this->_escape($this->UTF8ToLatin1('{'.$pk.'}'));
8137: $alias_pgc = $this->_escape($this->utf8StrRev($pk, false, $this->tmprtl));
8138: $alias_pgcu = $this->_escape($this->utf8StrRev('{'.$pk.'}', false, $this->tmprtl));
8139: }
8140: $temppage = str_replace($alias_pgau, $pvu, $temppage);
8141: if ($this->isunicode) {
8142: $temppage = str_replace($alias_pgbu, $pvu, $temppage);
8143: $temppage = str_replace($alias_pgcu, $pvu, $temppage);
8144: $temppage = str_replace($alias_pgb, $pvs, $temppage);
8145: $temppage = str_replace($alias_pgc, $pvs, $temppage);
8146: }
8147: $temppage = str_replace($alias_pga, $pvs, $temppage);
8148: }
8149: }
8150: if (!empty($this->AliasNbPages)) {
8151:
8152: $temppage = str_replace($alias_au, $nbu, $temppage);
8153: if ($this->isunicode) {
8154: $temppage = str_replace($alias_bu, $nbu, $temppage);
8155: $temppage = str_replace($alias_cu, $nbu, $temppage);
8156: $temppage = str_replace($alias_b, $nbs, $temppage);
8157: $temppage = str_replace($alias_c, $nbs, $temppage);
8158: }
8159: $temppage = str_replace($alias_a, $nbs, $temppage);
8160: }
8161: if (!empty($this->AliasNumPage)) {
8162:
8163: $pnbs = $this->formatPageNumber($n);
8164: $pnbu = $this->UTF8ToUTF16BE($pnbs, false);
8165: $temppage = str_replace($alias_pau, $pnbu, $temppage);
8166: if ($this->isunicode) {
8167: $temppage = str_replace($alias_pbu, $pnbu, $temppage);
8168: $temppage = str_replace($alias_pcu, $pnbu, $temppage);
8169: $temppage = str_replace($alias_pb, $pnbs, $temppage);
8170: $temppage = str_replace($alias_pc, $pnbs, $temppage);
8171: }
8172: $temppage = str_replace($alias_pa, $pnbs, $temppage);
8173: }
8174: $temppage = str_replace($this->epsmarker, '', $temppage);
8175:
8176: $this->page_obj_id[$n] = $this->_newobj();
8177: $out = '<<';
8178: $out .= ' /Type /Page';
8179: $out .= ' /Parent 1 0 R';
8180: $out .= ' /LastModified '.$this->_datestring();
8181: $out .= ' /Resources 2 0 R';
8182: $boxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');
8183: foreach ($boxes as $box) {
8184: $out .= ' /'.$box;
8185: $out .= sprintf(' [%.2F %.2F %.2F %.2F]', $this->pagedim[$n][$box]['llx'], $this->pagedim[$n][$box]['lly'], $this->pagedim[$n][$box]['urx'], $this->pagedim[$n][$box]['ury']);
8186: }
8187: if (isset($this->pagedim[$n]['BoxColorInfo']) AND !empty($this->pagedim[$n]['BoxColorInfo'])) {
8188: $out .= ' /BoxColorInfo <<';
8189: foreach ($boxes as $box) {
8190: if (isset($this->pagedim[$n]['BoxColorInfo'][$box])) {
8191: $out .= ' /'.$box.' <<';
8192: if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['C'])) {
8193: $color = $this->pagedim[$n]['BoxColorInfo'][$box]['C'];
8194: $out .= ' /C [';
8195: $out .= sprintf(' %.3F %.3F %.3F', $color[0]/255, $color[1]/255, $color[2]/255);
8196: $out .= ' ]';
8197: }
8198: if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['W'])) {
8199: $out .= ' /W '.($this->pagedim[$n]['BoxColorInfo'][$box]['W'] * $this->k);
8200: }
8201: if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['S'])) {
8202: $out .= ' /S /'.$this->pagedim[$n]['BoxColorInfo'][$box]['S'];
8203: }
8204: if (isset($this->pagedim[$n]['BoxColorInfo'][$box]['D'])) {
8205: $dashes = $this->pagedim[$n]['BoxColorInfo'][$box]['D'];
8206: $out .= ' /D [';
8207: foreach ($dashes as $dash) {
8208: $out .= sprintf(' %.3F', ($dash * $this->k));
8209: }
8210: $out .= ' ]';
8211: }
8212: $out .= ' >>';
8213: }
8214: }
8215: $out .= ' >>';
8216: }
8217: $out .= ' /Contents '.($this->n + 1).' 0 R';
8218: $out .= ' /Rotate '.$this->pagedim[$n]['Rotate'];
8219: $out .= ' /Group << /Type /Group /S /Transparency /CS /DeviceRGB >>';
8220: if (isset($this->pagedim[$n]['trans']) AND !empty($this->pagedim[$n]['trans'])) {
8221:
8222: if (isset($this->pagedim[$n]['trans']['Dur'])) {
8223: $out .= ' /Dur '.$this->pagedim[$n]['trans']['Dur'];
8224: }
8225: $out .= ' /Trans <<';
8226: $out .= ' /Type /Trans';
8227: if (isset($this->pagedim[$n]['trans']['S'])) {
8228: $out .= ' /S /'.$this->pagedim[$n]['trans']['S'];
8229: }
8230: if (isset($this->pagedim[$n]['trans']['D'])) {
8231: $out .= ' /D '.$this->pagedim[$n]['trans']['D'];
8232: }
8233: if (isset($this->pagedim[$n]['trans']['Dm'])) {
8234: $out .= ' /Dm /'.$this->pagedim[$n]['trans']['Dm'];
8235: }
8236: if (isset($this->pagedim[$n]['trans']['M'])) {
8237: $out .= ' /M /'.$this->pagedim[$n]['trans']['M'];
8238: }
8239: if (isset($this->pagedim[$n]['trans']['Di'])) {
8240: $out .= ' /Di '.$this->pagedim[$n]['trans']['Di'];
8241: }
8242: if (isset($this->pagedim[$n]['trans']['SS'])) {
8243: $out .= ' /SS '.$this->pagedim[$n]['trans']['SS'];
8244: }
8245: if (isset($this->pagedim[$n]['trans']['B'])) {
8246: $out .= ' /B '.$this->pagedim[$n]['trans']['B'];
8247: }
8248: $out .= ' >>';
8249: }
8250: $out .= $this->_getannotsrefs($n);
8251: $out .= ' /PZ '.$this->pagedim[$n]['PZ'];
8252: $out .= ' >>';
8253: $out .= "\n".'endobj';
8254: $this->_out($out);
8255:
8256: $p = ($this->compress) ? gzcompress($temppage) : $temppage;
8257: $this->_newobj();
8258: $p = $this->_getrawstream($p);
8259: $this->_out('<<'.$filter.'/Length '.strlen($p).'>> stream'."\n".$p."\n".'endstream'."\n".'endobj');
8260: if ($this->diskcache) {
8261:
8262: unlink($this->pages[$n]);
8263: }
8264: }
8265:
8266: $out = $this->_getobj(1)."\n";
8267: $out .= '<< /Type /Pages /Kids [';
8268: foreach($this->page_obj_id as $page_obj) {
8269: $out .= ' '.$page_obj.' 0 R';
8270: }
8271: $out .= ' ] /Count '.$nb.' >>';
8272: $out .= "\n".'endobj';
8273: $this->_out($out);
8274: }
8275:
8276: 8277: 8278: 8279: 8280: 8281: 8282: 8283:
8284: protected function _putannotsrefs($n) {
8285: $this->_out($this->_getannotsrefs($n));
8286: }
8287:
8288: 8289: 8290: 8291: 8292: 8293: 8294: 8295:
8296: protected function _getannotsrefs($n) {
8297: if (!(isset($this->PageAnnots[$n]) OR ($this->sign AND isset($this->signature_data['cert_type'])))) {
8298: return '';
8299: }
8300: $out = ' /Annots [';
8301: if (isset($this->PageAnnots[$n])) {
8302: foreach ($this->PageAnnots[$n] as $key => $val) {
8303: if (!in_array($val['n'], $this->radio_groups)) {
8304: $out .= ' '.$val['n'].' 0 R';
8305: }
8306: }
8307:
8308: if (isset($this->radiobutton_groups[$n])) {
8309: foreach ($this->radiobutton_groups[$n] as $key => $data) {
8310: if (isset($data['n'])) {
8311: $out .= ' '.$data['n'].' 0 R';
8312: }
8313: }
8314: }
8315: }
8316: if ($this->sign AND ($n == $this->signature_appearance['page']) AND isset($this->signature_data['cert_type'])) {
8317:
8318: $out .= ' '.$this->sig_obj_id.' 0 R';
8319: }
8320: $out .= ' ]';
8321: return $out;
8322: }
8323:
8324: 8325: 8326: 8327: 8328: 8329: 8330: 8331:
8332: protected function _putannotsobjs() {
8333:
8334: for ($n=1; $n <= $this->numpages; ++$n) {
8335: if (isset($this->PageAnnots[$n])) {
8336:
8337: foreach ($this->PageAnnots[$n] as $key => $pl) {
8338: $annot_obj_id = $this->PageAnnots[$n][$key]['n'];
8339:
8340: if (isset($this->radiobutton_groups[$n][$pl['txt']]) AND is_array($this->radiobutton_groups[$n][$pl['txt']])) {
8341: $radio_button_obj_id = $this->radiobutton_groups[$n][$pl['txt']]['n'];
8342: $annots = '<<';
8343: $annots .= ' /Type /Annot';
8344: $annots .= ' /Subtype /Widget';
8345: $annots .= ' /Rect [0 0 0 0]';
8346: $annots .= ' /T '.$this->_datastring($pl['txt'], $radio_button_obj_id);
8347: $annots .= ' /FT /Btn';
8348: $annots .= ' /Ff 49152';
8349: $annots .= ' /Kids [';
8350: foreach ($this->radiobutton_groups[$n][$pl['txt']] as $key => $data) {
8351: if ($key !== 'n') {
8352: $annots .= ' '.$data['kid'].' 0 R';
8353: if ($data['def'] !== 'Off') {
8354: $defval = $data['def'];
8355: }
8356: }
8357: }
8358: $annots .= ' ]';
8359: if (isset($defval)) {
8360: $annots .= ' /V /'.$defval;
8361: }
8362: $annots .= ' >>';
8363: $this->_out($this->_getobj($radio_button_obj_id)."\n".$annots."\n".'endobj');
8364: $this->form_obj_id[] = $radio_button_obj_id;
8365:
8366: $this->radiobutton_groups[$n][$pl['txt']] = $radio_button_obj_id;
8367: }
8368: $formfield = false;
8369: $pl['opt'] = array_change_key_case($pl['opt'], CASE_LOWER);
8370: $a = $pl['x'] * $this->k;
8371: $b = $this->pagedim[$n]['h'] - (($pl['y'] + $pl['h']) * $this->k);
8372: $c = $pl['w'] * $this->k;
8373: $d = $pl['h'] * $this->k;
8374: $rect = sprintf('%.2F %.2F %.2F %.2F', $a, $b, $a+$c, $b+$d);
8375:
8376: $annots = '<</Type /Annot';
8377: $annots .= ' /Subtype /'.$pl['opt']['subtype'];
8378: $annots .= ' /Rect ['.$rect.']';
8379: $ft = array('Btn', 'Tx', 'Ch', 'Sig');
8380: if (isset($pl['opt']['ft']) AND in_array($pl['opt']['ft'], $ft)) {
8381: $annots .= ' /FT /'.$pl['opt']['ft'];
8382: $formfield = true;
8383: }
8384: $annots .= ' /Contents '.$this->_textstring($pl['txt'], $annot_obj_id);
8385: $annots .= ' /P '.$this->page_obj_id[$n].' 0 R';
8386: $annots .= ' /NM '.$this->_datastring(sprintf('%04u-%04u', $n, $key), $annot_obj_id);
8387: $annots .= ' /M '.$this->_datestring($annot_obj_id);
8388: if (isset($pl['opt']['f'])) {
8389: $val = 0;
8390: if (is_array($pl['opt']['f'])) {
8391: foreach ($pl['opt']['f'] as $f) {
8392: switch (strtolower($f)) {
8393: case 'invisible': {
8394: $val += 1 << 0;
8395: break;
8396: }
8397: case 'hidden': {
8398: $val += 1 << 1;
8399: break;
8400: }
8401: case 'print': {
8402: $val += 1 << 2;
8403: break;
8404: }
8405: case 'nozoom': {
8406: $val += 1 << 3;
8407: break;
8408: }
8409: case 'norotate': {
8410: $val += 1 << 4;
8411: break;
8412: }
8413: case 'noview': {
8414: $val += 1 << 5;
8415: break;
8416: }
8417: case 'readonly': {
8418: $val += 1 << 6;
8419: break;
8420: }
8421: case 'locked': {
8422: $val += 1 << 8;
8423: break;
8424: }
8425: case 'togglenoview': {
8426: $val += 1 << 9;
8427: break;
8428: }
8429: case 'lockedcontents': {
8430: $val += 1 << 10;
8431: break;
8432: }
8433: default: {
8434: break;
8435: }
8436: }
8437: }
8438: } else {
8439: $val = intval($pl['opt']['f']);
8440: }
8441: $annots .= ' /F '.intval($val);
8442: }
8443: if (isset($pl['opt']['as']) AND is_string($pl['opt']['as'])) {
8444: $annots .= ' /AS /'.$pl['opt']['as'];
8445: }
8446: if (isset($pl['opt']['ap'])) {
8447:
8448: $annots .= ' /AP <<';
8449: if (is_array($pl['opt']['ap'])) {
8450: foreach ($pl['opt']['ap'] as $apmode => $apdef) {
8451:
8452: $annots .= ' /'.strtoupper($apmode);
8453: if (is_array($apdef)) {
8454: $annots .= ' <<';
8455: foreach ($apdef as $apstate => $stream) {
8456:
8457: $apsobjid = $this->_putAPXObject($c, $d, $stream);
8458: $annots .= ' /'.$apstate.' '.$apsobjid.' 0 R';
8459: }
8460: $annots .= ' >>';
8461: } else {
8462:
8463: $apsobjid = $this->_putAPXObject($c, $d, $apdef);
8464: $annots .= ' '.$apsobjid.' 0 R';
8465: }
8466: }
8467: } else {
8468: $annots .= $pl['opt']['ap'];
8469: }
8470: $annots .= ' >>';
8471: }
8472: if (isset($pl['opt']['bs']) AND (is_array($pl['opt']['bs']))) {
8473: $annots .= ' /BS <<';
8474: $annots .= ' /Type /Border';
8475: if (isset($pl['opt']['bs']['w'])) {
8476: $annots .= ' /W '.intval($pl['opt']['bs']['w']);
8477: }
8478: $bstyles = array('S', 'D', 'B', 'I', 'U');
8479: if (isset($pl['opt']['bs']['s']) AND in_array($pl['opt']['bs']['s'], $bstyles)) {
8480: $annots .= ' /S /'.$pl['opt']['bs']['s'];
8481: }
8482: if (isset($pl['opt']['bs']['d']) AND (is_array($pl['opt']['bs']['d']))) {
8483: $annots .= ' /D [';
8484: foreach ($pl['opt']['bs']['d'] as $cord) {
8485: $annots .= ' '.intval($cord);
8486: }
8487: $annots .= ']';
8488: }
8489: $annots .= ' >>';
8490: } else {
8491: $annots .= ' /Border [';
8492: if (isset($pl['opt']['border']) AND (count($pl['opt']['border']) >= 3)) {
8493: $annots .= intval($pl['opt']['border'][0]).' ';
8494: $annots .= intval($pl['opt']['border'][1]).' ';
8495: $annots .= intval($pl['opt']['border'][2]);
8496: if (isset($pl['opt']['border'][3]) AND is_array($pl['opt']['border'][3])) {
8497: $annots .= ' [';
8498: foreach ($pl['opt']['border'][3] as $dash) {
8499: $annots .= intval($dash).' ';
8500: }
8501: $annots .= ']';
8502: }
8503: } else {
8504: $annots .= '0 0 0';
8505: }
8506: $annots .= ']';
8507: }
8508: if (isset($pl['opt']['be']) AND (is_array($pl['opt']['be']))) {
8509: $annots .= ' /BE <<';
8510: $bstyles = array('S', 'C');
8511: if (isset($pl['opt']['be']['s']) AND in_array($pl['opt']['be']['s'], $markups)) {
8512: $annots .= ' /S /'.$pl['opt']['bs']['s'];
8513: } else {
8514: $annots .= ' /S /S';
8515: }
8516: if (isset($pl['opt']['be']['i']) AND ($pl['opt']['be']['i'] >= 0) AND ($pl['opt']['be']['i'] <= 2)) {
8517: $annots .= ' /I '.sprintf(' %.4F', $pl['opt']['be']['i']);
8518: }
8519: $annots .= '>>';
8520: }
8521: if (isset($pl['opt']['c']) AND (is_array($pl['opt']['c'])) AND !empty($pl['opt']['c'])) {
8522: $annots .= ' /C [';
8523: foreach ($pl['opt']['c'] as $col) {
8524: $col = intval($col);
8525: $color = $col <= 0 ? 0 : ($col >= 255 ? 1 : $col / 255);
8526: $annots .= sprintf(' %.4F', $color);
8527: }
8528: $annots .= ']';
8529: }
8530:
8531:
8532: $markups = array('text', 'freetext', 'line', 'square', 'circle', 'polygon', 'polyline', 'highlight', 'underline', 'squiggly', 'strikeout', 'stamp', 'caret', 'ink', 'fileattachment', 'sound');
8533: if (in_array(strtolower($pl['opt']['subtype']), $markups)) {
8534:
8535: if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
8536: $annots .= ' /T '.$this->_textstring($pl['opt']['t'], $annot_obj_id);
8537: }
8538:
8539: if (isset($pl['opt']['ca'])) {
8540: $annots .= ' /CA '.sprintf('%.4F', floatval($pl['opt']['ca']));
8541: }
8542: if (isset($pl['opt']['rc'])) {
8543: $annots .= ' /RC '.$this->_textstring($pl['opt']['rc'], $annot_obj_id);
8544: }
8545: $annots .= ' /CreationDate '.$this->_datestring($annot_obj_id);
8546:
8547: if (isset($pl['opt']['subj'])) {
8548: $annots .= ' /Subj '.$this->_textstring($pl['opt']['subj'], $annot_obj_id);
8549: }
8550:
8551:
8552:
8553: }
8554: $lineendings = array('Square', 'Circle', 'Diamond', 'OpenArrow', 'ClosedArrow', 'None', 'Butt', 'ROpenArrow', 'RClosedArrow', 'Slash');
8555:
8556: switch (strtolower($pl['opt']['subtype'])) {
8557: case 'text': {
8558: if (isset($pl['opt']['open'])) {
8559: $annots .= ' /Open '. (strtolower($pl['opt']['open']) == 'true' ? 'true' : 'false');
8560: }
8561: $iconsapp = array('Comment', 'Help', 'Insert', 'Key', 'NewParagraph', 'Note', 'Paragraph');
8562: if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
8563: $annots .= ' /Name /'.$pl['opt']['name'];
8564: } else {
8565: $annots .= ' /Name /Note';
8566: }
8567: $statemodels = array('Marked', 'Review');
8568: if (isset($pl['opt']['statemodel']) AND in_array($pl['opt']['statemodel'], $statemodels)) {
8569: $annots .= ' /StateModel /'.$pl['opt']['statemodel'];
8570: } else {
8571: $pl['opt']['statemodel'] = 'Marked';
8572: $annots .= ' /StateModel /'.$pl['opt']['statemodel'];
8573: }
8574: if ($pl['opt']['statemodel'] == 'Marked') {
8575: $states = array('Accepted', 'Unmarked');
8576: } else {
8577: $states = array('Accepted', 'Rejected', 'Cancelled', 'Completed', 'None');
8578: }
8579: if (isset($pl['opt']['state']) AND in_array($pl['opt']['state'], $states)) {
8580: $annots .= ' /State /'.$pl['opt']['state'];
8581: } else {
8582: if ($pl['opt']['statemodel'] == 'Marked') {
8583: $annots .= ' /State /Unmarked';
8584: } else {
8585: $annots .= ' /State /None';
8586: }
8587: }
8588: break;
8589: }
8590: case 'link': {
8591: if(is_string($pl['txt'])) {
8592:
8593: $annots .= ' /A <</S /URI /URI '.$this->_datastring($this->unhtmlentities($pl['txt']), $annot_obj_id).'>>';
8594: } else {
8595:
8596: $l = $this->links[$pl['txt']];
8597: $annots .= sprintf(' /Dest [%u 0 R /XYZ 0 %.2F null]', $this->page_obj_id[($l[0])], ($this->pagedim[$l[0]]['h'] - ($l[1] * $this->k)));
8598: }
8599: $hmodes = array('N', 'I', 'O', 'P');
8600: if (isset($pl['opt']['h']) AND in_array($pl['opt']['h'], $hmodes)) {
8601: $annots .= ' /H /'.$pl['opt']['h'];
8602: } else {
8603: $annots .= ' /H /I';
8604: }
8605:
8606:
8607: break;
8608: }
8609: case 'freetext': {
8610: if (isset($pl['opt']['da']) AND !empty($pl['opt']['da'])) {
8611: $annots .= ' /DA ('.$pl['opt']['da'].')';
8612: }
8613: if (isset($pl['opt']['q']) AND ($pl['opt']['q'] >= 0) AND ($pl['opt']['q'] <= 2)) {
8614: $annots .= ' /Q '.intval($pl['opt']['q']);
8615: }
8616: if (isset($pl['opt']['rc'])) {
8617: $annots .= ' /RC '.$this->_textstring($pl['opt']['rc'], $annot_obj_id);
8618: }
8619: if (isset($pl['opt']['ds'])) {
8620: $annots .= ' /DS '.$this->_textstring($pl['opt']['ds'], $annot_obj_id);
8621: }
8622: if (isset($pl['opt']['cl']) AND is_array($pl['opt']['cl'])) {
8623: $annots .= ' /CL [';
8624: foreach ($pl['opt']['cl'] as $cl) {
8625: $annots .= sprintf('%.4F ', $cl * $this->k);
8626: }
8627: $annots .= ']';
8628: }
8629: $tfit = array('FreeText', 'FreeTextCallout', 'FreeTextTypeWriter');
8630: if (isset($pl['opt']['it']) AND in_array($pl['opt']['it'], $tfit)) {
8631: $annots .= ' /IT /'.$pl['opt']['it'];
8632: }
8633: if (isset($pl['opt']['rd']) AND is_array($pl['opt']['rd'])) {
8634: $l = $pl['opt']['rd'][0] * $this->k;
8635: $r = $pl['opt']['rd'][1] * $this->k;
8636: $t = $pl['opt']['rd'][2] * $this->k;
8637: $b = $pl['opt']['rd'][3] * $this->k;
8638: $annots .= ' /RD ['.sprintf('%.2F %.2F %.2F %.2F', $l, $r, $t, $b).']';
8639: }
8640: if (isset($pl['opt']['le']) AND in_array($pl['opt']['le'], $lineendings)) {
8641: $annots .= ' /LE /'.$pl['opt']['le'];
8642: }
8643: break;
8644: }
8645: case 'line': {
8646: break;
8647: }
8648: case 'square': {
8649: break;
8650: }
8651: case 'circle': {
8652: break;
8653: }
8654: case 'polygon': {
8655: break;
8656: }
8657: case 'polyline': {
8658: break;
8659: }
8660: case 'highlight': {
8661: break;
8662: }
8663: case 'underline': {
8664: break;
8665: }
8666: case 'squiggly': {
8667: break;
8668: }
8669: case 'strikeout': {
8670: break;
8671: }
8672: case 'stamp': {
8673: break;
8674: }
8675: case 'caret': {
8676: break;
8677: }
8678: case 'ink': {
8679: break;
8680: }
8681: case 'popup': {
8682: break;
8683: }
8684: case 'fileattachment': {
8685: if (!isset($pl['opt']['fs'])) {
8686: break;
8687: }
8688: $filename = basename($pl['opt']['fs']);
8689: if (isset($this->embeddedfiles[$filename]['n'])) {
8690: $annots .= ' /FS <</Type /Filespec /F '.$this->_datastring($filename, $annot_obj_id).' /EF <</F '.$this->embeddedfiles[$filename]['n'].' 0 R>> >>';
8691: $iconsapp = array('Graph', 'Paperclip', 'PushPin', 'Tag');
8692: if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
8693: $annots .= ' /Name /'.$pl['opt']['name'];
8694: } else {
8695: $annots .= ' /Name /PushPin';
8696: }
8697: }
8698: break;
8699: }
8700: case 'sound': {
8701: if (!isset($pl['opt']['fs'])) {
8702: break;
8703: }
8704: $filename = basename($pl['opt']['fs']);
8705: if (isset($this->embeddedfiles[$filename]['n'])) {
8706:
8707:
8708: $annots .= ' /Sound <</Type /Filespec /F '.$this->_datastring($filename, $annot_obj_id).' /EF <</F '.$this->embeddedfiles[$filename]['n'].' 0 R>> >>';
8709: $iconsapp = array('Speaker', 'Mic');
8710: if (isset($pl['opt']['name']) AND in_array($pl['opt']['name'], $iconsapp)) {
8711: $annots .= ' /Name /'.$pl['opt']['name'];
8712: } else {
8713: $annots .= ' /Name /Speaker';
8714: }
8715: }
8716: break;
8717: }
8718: case 'movie': {
8719: break;
8720: }
8721: case 'widget': {
8722: $hmode = array('N', 'I', 'O', 'P', 'T');
8723: if (isset($pl['opt']['h']) AND in_array($pl['opt']['h'], $hmode)) {
8724: $annots .= ' /H /'.$pl['opt']['h'];
8725: }
8726: if (isset($pl['opt']['mk']) AND (is_array($pl['opt']['mk'])) AND !empty($pl['opt']['mk'])) {
8727: $annots .= ' /MK <<';
8728: if (isset($pl['opt']['mk']['r'])) {
8729: $annots .= ' /R '.$pl['opt']['mk']['r'];
8730: }
8731: if (isset($pl['opt']['mk']['bc']) AND (is_array($pl['opt']['mk']['bc']))) {
8732: $annots .= ' /BC [';
8733: foreach($pl['opt']['mk']['bc'] AS $col) {
8734: $col = intval($col);
8735: $color = $col <= 0 ? 0 : ($col >= 255 ? 1 : $col / 255);
8736: $annots .= sprintf(' %.2F', $color);
8737: }
8738: $annots .= ']';
8739: }
8740: if (isset($pl['opt']['mk']['bg']) AND (is_array($pl['opt']['mk']['bg']))) {
8741: $annots .= ' /BG [';
8742: foreach($pl['opt']['mk']['bg'] AS $col) {
8743: $col = intval($col);
8744: $color = $col <= 0 ? 0 : ($col >= 255 ? 1 : $col / 255);
8745: $annots .= sprintf(' %.2F', $color);
8746: }
8747: $annots .= ']';
8748: }
8749: if (isset($pl['opt']['mk']['ca'])) {
8750: $annots .= ' /CA '.$pl['opt']['mk']['ca'];
8751: }
8752: if (isset($pl['opt']['mk']['rc'])) {
8753: $annots .= ' /RC '.$pl['opt']['mk']['rc'];
8754: }
8755: if (isset($pl['opt']['mk']['ac'])) {
8756: $annots .= ' /AC '.$pl['opt']['mk']['ac'];
8757: }
8758: if (isset($pl['opt']['mk']['i'])) {
8759: $info = $this->getImageBuffer($pl['opt']['mk']['i']);
8760: if ($info !== false) {
8761: $annots .= ' /I '.$info['n'].' 0 R';
8762: }
8763: }
8764: if (isset($pl['opt']['mk']['ri'])) {
8765: $info = $this->getImageBuffer($pl['opt']['mk']['ri']);
8766: if ($info !== false) {
8767: $annots .= ' /RI '.$info['n'].' 0 R';
8768: }
8769: }
8770: if (isset($pl['opt']['mk']['ix'])) {
8771: $info = $this->getImageBuffer($pl['opt']['mk']['ix']);
8772: if ($info !== false) {
8773: $annots .= ' /IX '.$info['n'].' 0 R';
8774: }
8775: }
8776: if (isset($pl['opt']['mk']['if']) AND (is_array($pl['opt']['mk']['if'])) AND !empty($pl['opt']['mk']['if'])) {
8777: $annots .= ' /IF <<';
8778: $if_sw = array('A', 'B', 'S', 'N');
8779: if (isset($pl['opt']['mk']['if']['sw']) AND in_array($pl['opt']['mk']['if']['sw'], $if_sw)) {
8780: $annots .= ' /SW /'.$pl['opt']['mk']['if']['sw'];
8781: }
8782: $if_s = array('A', 'P');
8783: if (isset($pl['opt']['mk']['if']['s']) AND in_array($pl['opt']['mk']['if']['s'], $if_s)) {
8784: $annots .= ' /S /'.$pl['opt']['mk']['if']['s'];
8785: }
8786: if (isset($pl['opt']['mk']['if']['a']) AND (is_array($pl['opt']['mk']['if']['a'])) AND !empty($pl['opt']['mk']['if']['a'])) {
8787: $annots .= sprintf(' /A [%.2F %.2F]', $pl['opt']['mk']['if']['a'][0], $pl['opt']['mk']['if']['a'][1]);
8788: }
8789: if (isset($pl['opt']['mk']['if']['fb']) AND ($pl['opt']['mk']['if']['fb'])) {
8790: $annots .= ' /FB true';
8791: }
8792: $annots .= '>>';
8793: }
8794: if (isset($pl['opt']['mk']['tp']) AND ($pl['opt']['mk']['tp'] >= 0) AND ($pl['opt']['mk']['tp'] <= 6)) {
8795: $annots .= ' /TP '.intval($pl['opt']['mk']['tp']);
8796: } else {
8797: $annots .= ' /TP 0';
8798: }
8799: $annots .= '>>';
8800: }
8801:
8802: if (isset($this->radiobutton_groups[$n][$pl['txt']])) {
8803:
8804: $annots .= ' /Parent '.$this->radiobutton_groups[$n][$pl['txt']].' 0 R';
8805: }
8806: if (isset($pl['opt']['t']) AND is_string($pl['opt']['t'])) {
8807: $annots .= ' /T '.$this->_datastring($pl['opt']['t'], $annot_obj_id);
8808: }
8809: if (isset($pl['opt']['tu']) AND is_string($pl['opt']['tu'])) {
8810: $annots .= ' /TU '.$this->_datastring($pl['opt']['tu'], $annot_obj_id);
8811: }
8812: if (isset($pl['opt']['tm']) AND is_string($pl['opt']['tm'])) {
8813: $annots .= ' /TM '.$this->_datastring($pl['opt']['tm'], $annot_obj_id);
8814: }
8815: if (isset($pl['opt']['ff'])) {
8816: if (is_array($pl['opt']['ff'])) {
8817:
8818: $flag = 0;
8819: foreach($pl['opt']['ff'] as $val) {
8820: $flag += 1 << ($val - 1);
8821: }
8822: } else {
8823: $flag = intval($pl['opt']['ff']);
8824: }
8825: $annots .= ' /Ff '.$flag;
8826: }
8827: if (isset($pl['opt']['maxlen'])) {
8828: $annots .= ' /MaxLen '.intval($pl['opt']['maxlen']);
8829: }
8830: if (isset($pl['opt']['v'])) {
8831: $annots .= ' /V';
8832: if (is_array($pl['opt']['v'])) {
8833: foreach ($pl['opt']['v'] AS $optval) {
8834: if (is_float($optval)) {
8835: $optval = sprintf('%.2F', $optval);
8836: }
8837: $annots .= ' '.$optval;
8838: }
8839: } else {
8840: $annots .= ' '.$this->_textstring($pl['opt']['v'], $annot_obj_id);
8841: }
8842: }
8843: if (isset($pl['opt']['dv'])) {
8844: $annots .= ' /DV';
8845: if (is_array($pl['opt']['dv'])) {
8846: foreach ($pl['opt']['dv'] AS $optval) {
8847: if (is_float($optval)) {
8848: $optval = sprintf('%.2F', $optval);
8849: }
8850: $annots .= ' '.$optval;
8851: }
8852: } else {
8853: $annots .= ' '.$this->_textstring($pl['opt']['dv'], $annot_obj_id);
8854: }
8855: }
8856: if (isset($pl['opt']['rv'])) {
8857: $annots .= ' /RV';
8858: if (is_array($pl['opt']['rv'])) {
8859: foreach ($pl['opt']['rv'] AS $optval) {
8860: if (is_float($optval)) {
8861: $optval = sprintf('%.2F', $optval);
8862: }
8863: $annots .= ' '.$optval;
8864: }
8865: } else {
8866: $annots .= ' '.$this->_textstring($pl['opt']['rv'], $annot_obj_id);
8867: }
8868: }
8869: if (isset($pl['opt']['a']) AND !empty($pl['opt']['a'])) {
8870: $annots .= ' /A << '.$pl['opt']['a'].' >>';
8871: }
8872: if (isset($pl['opt']['aa']) AND !empty($pl['opt']['aa'])) {
8873: $annots .= ' /AA << '.$pl['opt']['aa'].' >>';
8874: }
8875: if (isset($pl['opt']['da']) AND !empty($pl['opt']['da'])) {
8876: $annots .= ' /DA ('.$pl['opt']['da'].')';
8877: }
8878: if (isset($pl['opt']['q']) AND ($pl['opt']['q'] >= 0) AND ($pl['opt']['q'] <= 2)) {
8879: $annots .= ' /Q '.intval($pl['opt']['q']);
8880: }
8881: if (isset($pl['opt']['opt']) AND (is_array($pl['opt']['opt'])) AND !empty($pl['opt']['opt'])) {
8882: $annots .= ' /Opt [';
8883: foreach($pl['opt']['opt'] AS $copt) {
8884: if (is_array($copt)) {
8885: $annots .= ' ['.$this->_textstring($copt[0], $annot_obj_id).' '.$this->_textstring($copt[1], $annot_obj_id).']';
8886: } else {
8887: $annots .= ' '.$this->_textstring($copt, $annot_obj_id);
8888: }
8889: }
8890: $annots .= ']';
8891: }
8892: if (isset($pl['opt']['ti'])) {
8893: $annots .= ' /TI '.intval($pl['opt']['ti']);
8894: }
8895: if (isset($pl['opt']['i']) AND (is_array($pl['opt']['i'])) AND !empty($pl['opt']['i'])) {
8896: $annots .= ' /I [';
8897: foreach($pl['opt']['i'] AS $copt) {
8898: $annots .= intval($copt).' ';
8899: }
8900: $annots .= ']';
8901: }
8902: break;
8903: }
8904: case 'screen': {
8905: break;
8906: }
8907: case 'printermark': {
8908: break;
8909: }
8910: case 'trapnet': {
8911: break;
8912: }
8913: case 'watermark': {
8914: break;
8915: }
8916: case '3d': {
8917: break;
8918: }
8919: default: {
8920: break;
8921: }
8922: }
8923: $annots .= '>>';
8924:
8925: $this->_out($this->_getobj($annot_obj_id)."\n".$annots."\n".'endobj');
8926: if ($formfield AND !isset($this->radiobutton_groups[$n][$pl['txt']])) {
8927:
8928: $this->form_obj_id[] = $annot_obj_id;
8929: }
8930: }
8931: }
8932: }
8933: }
8934:
8935: 8936: 8937: 8938: 8939: 8940: 8941: 8942: 8943:
8944: protected function _putAPXObject($w=0, $h=0, $stream='') {
8945: $stream = trim($stream);
8946: $out = $this->_getobj()."\n";
8947: $this->xobjects['AX'.$this->n] = array('n' => $this->n);
8948: $out .= '<<';
8949: $out .= ' /Type /XObject';
8950: $out .= ' /Subtype /Form';
8951: $out .= ' /FormType 1';
8952: if ($this->compress) {
8953: $stream = gzcompress($stream);
8954: $out .= ' /Filter /FlateDecode';
8955: }
8956: $rect = sprintf('%.2F %.2F', $w, $h);
8957: $out .= ' /BBox [0 0 '.$rect.']';
8958: $out .= ' /Matrix [1 0 0 1 0 0]';
8959: $out .= ' /Resources <<';
8960: $out .= ' /ProcSet [/PDF /Text]';
8961: $out .= ' /Font <<';
8962: foreach ($this->annotation_fonts as $fontkey => $fontid) {
8963: $out .= ' /F'.$fontid.' '.$this->font_obj_ids[$fontkey].' 0 R';
8964: }
8965: $out .= ' >>';
8966: $out .= ' >>';
8967: $stream = $this->_getrawstream($stream);
8968: $out .= ' /Length '.strlen($stream);
8969: $out .= ' >>';
8970: $out .= ' stream'."\n".$stream."\n".'endstream';
8971: $out .= "\n".'endobj';
8972: $this->_out($out);
8973: return $this->n;
8974: }
8975:
8976: 8977: 8978: 8979: 8980: 8981: 8982: 8983: 8984:
8985: protected function _getULONG(&$str, &$offset) {
8986: $v = unpack('Ni', substr($str, $offset, 4));
8987: $offset += 4;
8988: return $v['i'];
8989: }
8990:
8991: 8992: 8993: 8994: 8995: 8996: 8997: 8998: 8999:
9000: protected function _getUSHORT(&$str, &$offset) {
9001: $v = unpack('ni', substr($str, $offset, 2));
9002: $offset += 2;
9003: return $v['i'];
9004: }
9005:
9006: 9007: 9008: 9009: 9010: 9011: 9012: 9013: 9014:
9015: protected function _getSHORT(&$str, &$offset) {
9016: $v = unpack('si', substr($str, $offset, 2));
9017: $offset += 2;
9018: return $v['i'];
9019: }
9020:
9021: 9022: 9023: 9024: 9025: 9026: 9027: 9028: 9029:
9030: protected function _getBYTE(&$str, &$offset) {
9031: $v = unpack('Ci', substr($str, $offset, 1));
9032: ++$offset;
9033: return $v['i'];
9034: }
9035:
9036: 9037: 9038: 9039: 9040: 9041: 9042: 9043: 9044:
9045: protected function _getTrueTypeFontSubset($font, $subsetchars) {
9046: ksort($subsetchars);
9047: $offset = 0;
9048: if ($this->_getULONG($font, $offset) != 0x10000) {
9049:
9050: return $font;
9051: }
9052:
9053: $numTables = $this->_getUSHORT($font, $offset);
9054:
9055: $offset += 6;
9056:
9057: $table = array();
9058:
9059: for ($i = 0; $i < $numTables; ++$i) {
9060:
9061: $tag = substr($font, $offset, 4);
9062: $offset += 4;
9063: $table[$tag] = array();
9064: $table[$tag]['checkSum'] = $this->_getULONG($font, $offset);
9065: $table[$tag]['offset'] = $this->_getULONG($font, $offset);
9066: $table[$tag]['length'] = $this->_getULONG($font, $offset);
9067: }
9068:
9069: $offset = $table['head']['offset'] + 12;
9070: if ($this->_getULONG($font, $offset) != 0x5F0F3CF5) {
9071:
9072: return $font;
9073: }
9074:
9075: $offset = $table['head']['offset'] + 50;
9076: $short_offset = ($this->_getSHORT($font, $offset) == 0);
9077:
9078: $indexToLoc = array();
9079: $offset = $table['loca']['offset'];
9080: if ($short_offset) {
9081:
9082: $n = $table['loca']['length'] / 2;
9083: for ($i = 0; $i < $n; ++$i) {
9084: $indexToLoc[$i] = $this->_getUSHORT($font, $offset) * 2;
9085: }
9086: } else {
9087:
9088: $n = $table['loca']['length'] / 4;
9089: for ($i = 0; $i < $n; ++$i) {
9090: $indexToLoc[$i] = $this->_getULONG($font, $offset);
9091: }
9092: }
9093:
9094: $subsetglyphs = array();
9095: $subsetglyphs[0] = true;
9096: $offset = $table['cmap']['offset'] + 2;
9097: $numEncodingTables = $this->_getUSHORT($font, $offset);
9098: $encodingTables = array();
9099: for ($i = 0; $i < $numEncodingTables; ++$i) {
9100: $encodingTables[$i]['platformID'] = $this->_getUSHORT($font, $offset);
9101: $encodingTables[$i]['encodingID'] = $this->_getUSHORT($font, $offset);
9102: $encodingTables[$i]['offset'] = $this->_getULONG($font, $offset);
9103: }
9104: foreach ($encodingTables as $enctable) {
9105: if (($enctable['platformID'] == 3) AND ($enctable['encodingID'] == 0)) {
9106: $modesymbol = true;
9107: } else {
9108: $modesymbol = false;
9109: }
9110: $offset = $table['cmap']['offset'] + $enctable['offset'];
9111: $format = $this->_getUSHORT($font, $offset);
9112: switch ($format) {
9113: case 0: {
9114: $offset += 4;
9115: for ($k = 0; $k < 256; ++$k) {
9116: if (isset($subsetchars[$k])) {
9117: $g = $this->_getBYTE($font, $offset);
9118: $subsetglyphs[$g] = $k;
9119: } else {
9120: ++$offset;
9121: }
9122: }
9123: break;
9124: }
9125: case 2: {
9126: $offset += 4;
9127:
9128: break;
9129: }
9130: case 4: {
9131: $length = $this->_getUSHORT($font, $offset);
9132: $offset += 2;
9133: $segCount = ($this->_getUSHORT($font, $offset) / 2);
9134: $offset += 6;
9135: $endCount = array();
9136: for ($k = 0; $k < $segCount; ++$k) {
9137: $endCount[$k] = $this->_getUSHORT($font, $offset);
9138: }
9139: $offset += 2;
9140: $startCount = array();
9141: for ($k = 0; $k < $segCount; ++$k) {
9142: $startCount[$k] = $this->_getUSHORT($font, $offset);
9143: }
9144: $idDelta = array();
9145: for ($k = 0; $k < $segCount; ++$k) {
9146: $idDelta[$k] = $this->_getUSHORT($font, $offset);
9147: }
9148: $idRangeOffset = array();
9149: for ($k = 0; $k < $segCount; ++$k) {
9150: $idRangeOffset[$k] = $this->_getUSHORT($font, $offset);
9151: }
9152: $gidlen = ($length / 2) - 8 - (4 * $segCount);
9153: $glyphIdArray = array();
9154: for ($k = 0; $k < $gidlen; ++$k) {
9155: $glyphIdArray[$k] = $this->_getUSHORT($font, $offset);
9156: }
9157: for ($k = 0; $k < $segCount; ++$k) {
9158: for ($c = $startCount[$k]; $c <= $endCount[$k]; ++$c) {
9159: if (isset($subsetchars[$c])) {
9160: if ($idRangeOffset[$k] == 0) {
9161: $g = $c;
9162: } else {
9163: $gid = (($idRangeOffset[$k] / 2) + ($c - $startCount[$k]) - ($segCount - $k));
9164: $g = $glyphIdArray[$gid];
9165: }
9166: $g += ($idDelta[$k] - 65536);
9167: if ($g < 0) {
9168: $g = 0;
9169: }
9170: $subsetglyphs[$g] = $c;
9171: }
9172: }
9173: }
9174: break;
9175: }
9176: case 6: {
9177: $offset += 4;
9178: $firstCode = $this->_getUSHORT($font, $offset);
9179: $entryCount = $this->_getUSHORT($font, $offset);
9180: for ($k = 0; $k < $entryCount; ++$k) {
9181: $c = ($k + $firstCode);
9182: if (isset($subsetchars[$c])) {
9183: $g = $this->_getUSHORT($font, $offset);
9184: $subsetglyphs[$g] = $c;
9185: } else {
9186: $offset += 2;
9187: }
9188: }
9189: break;
9190: }
9191: case 8: {
9192: $offset += 10;
9193:
9194: break;
9195: }
9196: case 10: {
9197: $offset += 10;
9198: $startCharCode = $this->_getULONG($font, $offset);
9199: $numChars = $this->_getULONG($font, $offset);
9200: for ($k = 0; $k < $numChars; ++$k) {
9201: $c = ($k + $startCharCode);
9202: if (isset($subsetchars[$c])) {
9203: $g = $this->_getUSHORT($font, $offset);
9204: $subsetglyphs[$g] = $c;
9205: } else {
9206: $offset += 2;
9207: }
9208: }
9209: break;
9210: }
9211: case 12: {
9212: $offset += 10;
9213: $nGroups = $this->_getULONG($font, $offset);
9214: for ($k = 0; $k < $nGroups; ++$k) {
9215: $startCharCode = $this->_getULONG($font, $offset);
9216: $endCharCode = $this->_getULONG($font, $offset);
9217: $startGlyphCode = $this->_getULONG($font, $offset);
9218: for ($c = $startCharCode; $c <= $endCharCode; ++$c) {
9219: if (isset($subsetchars[$c])) {
9220: $subsetglyphs[$startGlyphCode] = $c;
9221: }
9222: ++$startGlyphCode;
9223: }
9224: }
9225: break;
9226: }
9227: }
9228: }
9229:
9230: ksort($subsetglyphs);
9231:
9232: foreach ($subsetglyphs as $key => $val) {
9233: if (isset($indexToLoc[$key])) {
9234: $offset = $table['glyf']['offset'] + $indexToLoc[$key];
9235: $numberOfContours = $this->_getSHORT($font, $offset);
9236: if ($numberOfContours < 0) {
9237: $offset += 8;
9238: do {
9239: $flags = $this->_getUSHORT($font, $offset);
9240: $glyphIndex = $this->_getUSHORT($font, $offset);
9241: if (!isset($subsetglyphs[$glyphIndex]) AND isset($indexToLoc[$glyphIndex])) {
9242:
9243: $subsetglyphs[$glyphIndex] = true;
9244: }
9245:
9246: if ($flags & 1) {
9247: $offset += 4;
9248: } else {
9249: $offset += 2;
9250: }
9251: if ($flags & 8) {
9252: $offset += 2;
9253: } elseif ($flags & 64) {
9254: $offset += 4;
9255: } elseif ($flags & 128) {
9256: $offset += 8;
9257: }
9258: } while ($flags & 32);
9259: }
9260: } else {
9261: unset($subsetglyphs[$key]);
9262: }
9263: }
9264:
9265: $glyf = '';
9266: $glyfSize = 0;
9267:
9268: $newIndexToLoc = array_fill(0, count($indexToLoc), 0);
9269: $goffset = 0;
9270: foreach ($subsetglyphs as $glyphID => $char) {
9271: if (isset($indexToLoc[$glyphID]) AND isset($indexToLoc[($glyphID + 1)])) {
9272: $start = $indexToLoc[$glyphID];
9273: $length = ($indexToLoc[($glyphID + 1)] - $start);
9274: $glyf .= substr($font, ($table['glyf']['offset'] + $start), $length);
9275: $newIndexToLoc[$glyphID] = $goffset;
9276: $goffset += $length;
9277: }
9278: }
9279:
9280: $loca = '';
9281: if ($short_offset) {
9282: foreach ($newIndexToLoc as $glyphID => $offset) {
9283: $loca .= pack('n', ($offset / 2));
9284: }
9285: } else {
9286: foreach ($newIndexToLoc as $glyphID => $offset) {
9287: $loca .= pack('N', $offset);
9288: }
9289: }
9290:
9291:
9292:
9293: $table_names = array ('head', 'hhea', 'hmtx', 'maxp', 'cvt ', 'fpgm', 'prep');
9294:
9295: $offset = 12;
9296: foreach ($table as $tag => $val) {
9297: if (in_array($tag, $table_names)) {
9298: $table[$tag]['data'] = substr($font, $table[$tag]['offset'], $table[$tag]['length']);
9299: if ($tag == 'head') {
9300:
9301: $table[$tag]['data'] = substr($table[$tag]['data'], 0, 8)."\x0\x0\x0\x0".substr($table[$tag]['data'], 12);
9302: }
9303: $pad = 4 - ($table[$tag]['length'] % 4);
9304: if ($pad != 4) {
9305:
9306: $table[$tag]['length'] += $pad;
9307: $table[$tag]['data'] .= str_repeat("\x0", $pad);
9308: }
9309: $table[$tag]['offset'] = $offset;
9310: $offset += $table[$tag]['length'];
9311:
9312:
9313: } else {
9314: unset($table[$tag]);
9315: }
9316: }
9317:
9318: $table['loca']['data'] = $loca;
9319: $table['loca']['length'] = strlen($loca);
9320: $pad = 4 - ($table['loca']['length'] % 4);
9321: if ($pad != 4) {
9322:
9323: $table['loca']['length'] += $pad;
9324: $table['loca']['data'] .= str_repeat("\x0", $pad);
9325: }
9326: $table['loca']['offset'] = $offset;
9327: $table['loca']['checkSum'] = $this->_getTTFtableChecksum($table['loca']['data'], $table['loca']['length']);
9328: $offset += $table['loca']['length'];
9329:
9330: $table['glyf']['data'] = $glyf;
9331: $table['glyf']['length'] = strlen($glyf);
9332: $pad = 4 - ($table['glyf']['length'] % 4);
9333: if ($pad != 4) {
9334:
9335: $table['glyf']['length'] += $pad;
9336: $table['glyf']['data'] .= str_repeat("\x0", $pad);
9337: }
9338: $table['glyf']['offset'] = $offset;
9339: $table['glyf']['checkSum'] = $this->_getTTFtableChecksum($table['glyf']['data'], $table['glyf']['length']);
9340:
9341: $font = '';
9342: $font .= pack('N', 0x10000);
9343: $numTables = count($table);
9344: $font .= pack('n', $numTables);
9345: $entrySelector = floor(log($numTables, 2));
9346: $searchRange = pow(2, $entrySelector) * 16;
9347: $rangeShift = ($numTables * 16) - $searchRange;
9348: $font .= pack('n', $searchRange);
9349: $font .= pack('n', $entrySelector);
9350: $font .= pack('n', $rangeShift);
9351: $offset = ($numTables * 16);
9352: foreach ($table as $tag => $data) {
9353: $font .= $tag;
9354: $font .= pack('N', $data['checkSum']);
9355: $font .= pack('N', ($data['offset'] + $offset));
9356: $font .= pack('N', $data['length']);
9357: }
9358: foreach ($table as $data) {
9359: $font .= $data['data'];
9360: }
9361:
9362: $checkSumAdjustment = 0xB1B0AFBA - $this->_getTTFtableChecksum($font, strlen($font));
9363: $font = substr($font, 0, $table['head']['offset'] + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + 12);
9364: return $font;
9365: }
9366:
9367: 9368: 9369: 9370: 9371: 9372: 9373: 9374: 9375:
9376: protected function _getTTFtableChecksum($table, $length) {
9377: $sum = 0;
9378: $tlen = ($length / 4);
9379: $offset = 0;
9380: for ($i = 0; $i < $tlen; ++$i) {
9381: $v = unpack('Ni', substr($table, $offset, 4));
9382: $sum += $v['i'];
9383: $offset += 4;
9384: }
9385: $sum = unpack('Ni', pack('N', $sum));
9386: return $sum['i'];
9387: }
9388:
9389: 9390: 9391: 9392: 9393: 9394: 9395: 9396: 9397:
9398: protected function _putfontwidths($font, $cidoffset=0) {
9399: ksort($font['cw']);
9400: $rangeid = 0;
9401: $range = array();
9402: $prevcid = -2;
9403: $prevwidth = -1;
9404: $interval = false;
9405:
9406: foreach ($font['cw'] as $cid => $width) {
9407: $cid -= $cidoffset;
9408: if ($font['subset'] AND ($cid > 255) AND (!isset($font['subsetchars'][$cid]))) {
9409:
9410: continue;
9411: }
9412: if ($width != $font['dw']) {
9413: if ($cid == ($prevcid + 1)) {
9414:
9415: if ($width == $prevwidth) {
9416: if ($width == $range[$rangeid][0]) {
9417: $range[$rangeid][] = $width;
9418: } else {
9419: array_pop($range[$rangeid]);
9420:
9421: $rangeid = $prevcid;
9422: $range[$rangeid] = array();
9423: $range[$rangeid][] = $prevwidth;
9424: $range[$rangeid][] = $width;
9425: }
9426: $interval = true;
9427: $range[$rangeid]['interval'] = true;
9428: } else {
9429: if ($interval) {
9430:
9431: $rangeid = $cid;
9432: $range[$rangeid] = array();
9433: $range[$rangeid][] = $width;
9434: } else {
9435: $range[$rangeid][] = $width;
9436: }
9437: $interval = false;
9438: }
9439: } else {
9440:
9441: $rangeid = $cid;
9442: $range[$rangeid] = array();
9443: $range[$rangeid][] = $width;
9444: $interval = false;
9445: }
9446: $prevcid = $cid;
9447: $prevwidth = $width;
9448: }
9449: }
9450:
9451: $prevk = -1;
9452: $nextk = -1;
9453: $prevint = false;
9454: foreach ($range as $k => $ws) {
9455: $cws = count($ws);
9456: if (($k == $nextk) AND (!$prevint) AND ((!isset($ws['interval'])) OR ($cws < 4))) {
9457: if (isset($range[$k]['interval'])) {
9458: unset($range[$k]['interval']);
9459: }
9460: $range[$prevk] = array_merge($range[$prevk], $range[$k]);
9461: unset($range[$k]);
9462: } else {
9463: $prevk = $k;
9464: }
9465: $nextk = $k + $cws;
9466: if (isset($ws['interval'])) {
9467: if ($cws > 3) {
9468: $prevint = true;
9469: } else {
9470: $prevint = false;
9471: }
9472: unset($range[$k]['interval']);
9473: --$nextk;
9474: } else {
9475: $prevint = false;
9476: }
9477: }
9478:
9479: $w = '';
9480: foreach ($range as $k => $ws) {
9481: if (count(array_count_values($ws)) == 1) {
9482:
9483: $w .= ' '.$k.' '.($k + count($ws) - 1).' '.$ws[0];
9484: } else {
9485:
9486: $w .= ' '.$k.' [ '.implode(' ', $ws).' ]';
9487: }
9488: }
9489: return '/W ['.$w.' ]';
9490: }
9491:
9492: 9493: 9494: 9495: 9496:
9497: protected function _putfonts() {
9498: $nf = $this->n;
9499: foreach ($this->diffs as $diff) {
9500:
9501: $this->_newobj();
9502: $this->_out('<< /Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.'] >>'."\n".'endobj');
9503: }
9504: $mqr = $this->get_mqr();
9505: $this->set_mqr(false);
9506: foreach ($this->FontFiles as $file => $info) {
9507:
9508: $fontdir = $info['fontdir'];
9509: $file = strtolower($file);
9510: $fontfile = '';
9511:
9512: if (($fontdir !== false) AND file_exists($fontdir.$file)) {
9513: $fontfile = $fontdir.$file;
9514: } elseif (file_exists($this->_getfontpath().$file)) {
9515: $fontfile = $this->_getfontpath().$file;
9516: } elseif (file_exists($file)) {
9517: $fontfile = $file;
9518: }
9519: if (!$this->empty_string($fontfile)) {
9520: $font = file_get_contents($fontfile);
9521: $compressed = (substr($file, -2) == '.z');
9522: if ((!$compressed) AND (isset($info['length2']))) {
9523: $header = (ord($font{0}) == 128);
9524: if ($header) {
9525:
9526: $font = substr($font, 6);
9527: }
9528: if ($header AND (ord($font{$info['length1']}) == 128)) {
9529:
9530: $font = substr($font, 0, $info['length1']).substr($font, ($info['length1'] + 6));
9531: }
9532: } elseif ($info['subset'] AND ((!$compressed) OR ($compressed AND function_exists('gzcompress')))) {
9533: if ($compressed) {
9534:
9535: $font = gzuncompress($font);
9536: }
9537:
9538: $subsetchars = array();
9539: foreach ($info['fontkeys'] as $fontkey) {
9540: $fontinfo = $this->getFontBuffer($fontkey);
9541: $subsetchars += $fontinfo['subsetchars'];
9542: }
9543: $font = $this->_getTrueTypeFontSubset($font, $subsetchars);
9544: if ($compressed) {
9545:
9546: $font = gzcompress($font);
9547: }
9548: }
9549: $this->_newobj();
9550: $this->FontFiles[$file]['n'] = $this->n;
9551: $stream = $this->_getrawstream($font);
9552: $out = '<< /Length '.strlen($stream);
9553: if ($compressed) {
9554: $out .= ' /Filter /FlateDecode';
9555: }
9556: $out .= ' /Length1 '.$info['length1'];
9557: if (isset($info['length2'])) {
9558: $out .= ' /Length2 '.$info['length2'].' /Length3 0';
9559: }
9560: $out .= ' >>';
9561: $out .= ' stream'."\n".$stream."\n".'endstream';
9562: $out .= "\n".'endobj';
9563: $this->_out($out);
9564: }
9565: }
9566: $this->set_mqr($mqr);
9567: foreach ($this->fontkeys as $k) {
9568:
9569: $font = $this->getFontBuffer($k);
9570: $type = $font['type'];
9571: $name = $font['name'];
9572: if ($type == 'core') {
9573:
9574: $out = $this->_getobj($this->font_obj_ids[$k])."\n";
9575: $out .= '<</Type /Font';
9576: $out .= ' /Subtype /Type1';
9577: $out .= ' /BaseFont /'.$name;
9578: $out .= ' /Name /F'.$font['i'];
9579: if ((strtolower($name) != 'symbol') AND (strtolower($name) != 'zapfdingbats')) {
9580: $out .= ' /Encoding /WinAnsiEncoding';
9581: }
9582: if ($k == 'helvetica') {
9583:
9584: $this->annotation_fonts[$k] = $font['i'];
9585: }
9586: $out .= ' >>';
9587: $out .= "\n".'endobj';
9588: $this->_out($out);
9589: } elseif (($type == 'Type1') OR ($type == 'TrueType')) {
9590:
9591: $out = $this->_getobj($this->font_obj_ids[$k])."\n";
9592: $out .= '<</Type /Font';
9593: $out .= ' /Subtype /'.$type;
9594: $out .= ' /BaseFont /'.$name;
9595: $out .= ' /Name /F'.$font['i'];
9596: $out .= ' /FirstChar 32 /LastChar 255';
9597: $out .= ' /Widths '.($this->n + 1).' 0 R';
9598: $out .= ' /FontDescriptor '.($this->n + 2).' 0 R';
9599: if ($font['enc']) {
9600: if (isset($font['diff'])) {
9601: $out .= ' /Encoding '.($nf + $font['diff']).' 0 R';
9602: } else {
9603: $out .= ' /Encoding /WinAnsiEncoding';
9604: }
9605: }
9606: $out .= ' >>';
9607: $out .= "\n".'endobj';
9608: $this->_out($out);
9609:
9610: $this->_newobj();
9611: $cw = &$font['cw'];
9612: $s = '[';
9613: for ($i = 32; $i < 256; ++$i) {
9614: $s .= $cw[$i].' ';
9615: }
9616: $s .= ']';
9617: $s .= "\n".'endobj';
9618: $this->_out($s);
9619:
9620: $this->_newobj();
9621: $s = '<</Type /FontDescriptor /FontName /'.$name;
9622: foreach ($font['desc'] as $fdk => $fdv) {
9623: if(is_float($fdv)) {
9624: $fdv = sprintf('%.3F', $fdv);
9625: }
9626: $s .= ' /'.$fdk.' '.$fdv.'';
9627: }
9628: if (!$this->empty_string($font['file'])) {
9629: $s .= ' /FontFile'.($type == 'Type1' ? '' : '2').' '.$this->FontFiles[$font['file']]['n'].' 0 R';
9630: }
9631: $s .= '>>';
9632: $s .= "\n".'endobj';
9633: $this->_out($s);
9634: } else {
9635:
9636: $mtd = '_put'.strtolower($type);
9637: if (!method_exists($this, $mtd)) {
9638: $this->Error('Unsupported font type: '.$type);
9639: }
9640: $this->$mtd($font);
9641: }
9642: }
9643: }
9644:
9645: 9646: 9647: 9648: 9649: 9650: 9651: 9652:
9653: protected function _puttruetypeunicode($font) {
9654: $fontname = '';
9655: if ($font['subset']) {
9656:
9657: $subtag = sprintf('%06u', $font['i']);
9658: $subtag = strtr($subtag, '0123456789', 'ABCDEFGHIJ');
9659: $fontname .= $subtag.'+';
9660: }
9661: $fontname .= $font['name'];
9662:
9663:
9664: $out = $this->_getobj($this->font_obj_ids[$font['fontkey']])."\n";
9665: $out .= '<< /Type /Font';
9666: $out .= ' /Subtype /Type0';
9667: $out .= ' /BaseFont /'.$fontname;
9668: $out .= ' /Name /F'.$font['i'];
9669: $out .= ' /Encoding /'.$font['enc'];
9670: $out .= ' /ToUnicode '.($this->n + 1).' 0 R';
9671: $out .= ' /DescendantFonts ['.($this->n + 2).' 0 R]';
9672: $out .= ' >>';
9673: $out .= "\n".'endobj';
9674: $this->_out($out);
9675:
9676: $stream = "/CIDInit /ProcSet findresource begin\n";
9677: $stream .= "12 dict begin\n";
9678: $stream .= "begincmap\n";
9679: $stream .= "/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def\n";
9680: $stream .= "/CMapName /Adobe-Identity-UCS def\n";
9681: $stream .= "/CMapType 2 def\n";
9682: $stream .= "/WMode 0 def\n";
9683: $stream .= "1 begincodespacerange\n";
9684: $stream .= "<0000> <FFFF>\n";
9685: $stream .= "endcodespacerange\n";
9686: $stream .= "100 beginbfrange\n";
9687: $stream .= "<0000> <00ff> <0000>\n";
9688: $stream .= "<0100> <01ff> <0100>\n";
9689: $stream .= "<0200> <02ff> <0200>\n";
9690: $stream .= "<0300> <03ff> <0300>\n";
9691: $stream .= "<0400> <04ff> <0400>\n";
9692: $stream .= "<0500> <05ff> <0500>\n";
9693: $stream .= "<0600> <06ff> <0600>\n";
9694: $stream .= "<0700> <07ff> <0700>\n";
9695: $stream .= "<0800> <08ff> <0800>\n";
9696: $stream .= "<0900> <09ff> <0900>\n";
9697: $stream .= "<0a00> <0aff> <0a00>\n";
9698: $stream .= "<0b00> <0bff> <0b00>\n";
9699: $stream .= "<0c00> <0cff> <0c00>\n";
9700: $stream .= "<0d00> <0dff> <0d00>\n";
9701: $stream .= "<0e00> <0eff> <0e00>\n";
9702: $stream .= "<0f00> <0fff> <0f00>\n";
9703: $stream .= "<1000> <10ff> <1000>\n";
9704: $stream .= "<1100> <11ff> <1100>\n";
9705: $stream .= "<1200> <12ff> <1200>\n";
9706: $stream .= "<1300> <13ff> <1300>\n";
9707: $stream .= "<1400> <14ff> <1400>\n";
9708: $stream .= "<1500> <15ff> <1500>\n";
9709: $stream .= "<1600> <16ff> <1600>\n";
9710: $stream .= "<1700> <17ff> <1700>\n";
9711: $stream .= "<1800> <18ff> <1800>\n";
9712: $stream .= "<1900> <19ff> <1900>\n";
9713: $stream .= "<1a00> <1aff> <1a00>\n";
9714: $stream .= "<1b00> <1bff> <1b00>\n";
9715: $stream .= "<1c00> <1cff> <1c00>\n";
9716: $stream .= "<1d00> <1dff> <1d00>\n";
9717: $stream .= "<1e00> <1eff> <1e00>\n";
9718: $stream .= "<1f00> <1fff> <1f00>\n";
9719: $stream .= "<2000> <20ff> <2000>\n";
9720: $stream .= "<2100> <21ff> <2100>\n";
9721: $stream .= "<2200> <22ff> <2200>\n";
9722: $stream .= "<2300> <23ff> <2300>\n";
9723: $stream .= "<2400> <24ff> <2400>\n";
9724: $stream .= "<2500> <25ff> <2500>\n";
9725: $stream .= "<2600> <26ff> <2600>\n";
9726: $stream .= "<2700> <27ff> <2700>\n";
9727: $stream .= "<2800> <28ff> <2800>\n";
9728: $stream .= "<2900> <29ff> <2900>\n";
9729: $stream .= "<2a00> <2aff> <2a00>\n";
9730: $stream .= "<2b00> <2bff> <2b00>\n";
9731: $stream .= "<2c00> <2cff> <2c00>\n";
9732: $stream .= "<2d00> <2dff> <2d00>\n";
9733: $stream .= "<2e00> <2eff> <2e00>\n";
9734: $stream .= "<2f00> <2fff> <2f00>\n";
9735: $stream .= "<3000> <30ff> <3000>\n";
9736: $stream .= "<3100> <31ff> <3100>\n";
9737: $stream .= "<3200> <32ff> <3200>\n";
9738: $stream .= "<3300> <33ff> <3300>\n";
9739: $stream .= "<3400> <34ff> <3400>\n";
9740: $stream .= "<3500> <35ff> <3500>\n";
9741: $stream .= "<3600> <36ff> <3600>\n";
9742: $stream .= "<3700> <37ff> <3700>\n";
9743: $stream .= "<3800> <38ff> <3800>\n";
9744: $stream .= "<3900> <39ff> <3900>\n";
9745: $stream .= "<3a00> <3aff> <3a00>\n";
9746: $stream .= "<3b00> <3bff> <3b00>\n";
9747: $stream .= "<3c00> <3cff> <3c00>\n";
9748: $stream .= "<3d00> <3dff> <3d00>\n";
9749: $stream .= "<3e00> <3eff> <3e00>\n";
9750: $stream .= "<3f00> <3fff> <3f00>\n";
9751: $stream .= "<4000> <40ff> <4000>\n";
9752: $stream .= "<4100> <41ff> <4100>\n";
9753: $stream .= "<4200> <42ff> <4200>\n";
9754: $stream .= "<4300> <43ff> <4300>\n";
9755: $stream .= "<4400> <44ff> <4400>\n";
9756: $stream .= "<4500> <45ff> <4500>\n";
9757: $stream .= "<4600> <46ff> <4600>\n";
9758: $stream .= "<4700> <47ff> <4700>\n";
9759: $stream .= "<4800> <48ff> <4800>\n";
9760: $stream .= "<4900> <49ff> <4900>\n";
9761: $stream .= "<4a00> <4aff> <4a00>\n";
9762: $stream .= "<4b00> <4bff> <4b00>\n";
9763: $stream .= "<4c00> <4cff> <4c00>\n";
9764: $stream .= "<4d00> <4dff> <4d00>\n";
9765: $stream .= "<4e00> <4eff> <4e00>\n";
9766: $stream .= "<4f00> <4fff> <4f00>\n";
9767: $stream .= "<5000> <50ff> <5000>\n";
9768: $stream .= "<5100> <51ff> <5100>\n";
9769: $stream .= "<5200> <52ff> <5200>\n";
9770: $stream .= "<5300> <53ff> <5300>\n";
9771: $stream .= "<5400> <54ff> <5400>\n";
9772: $stream .= "<5500> <55ff> <5500>\n";
9773: $stream .= "<5600> <56ff> <5600>\n";
9774: $stream .= "<5700> <57ff> <5700>\n";
9775: $stream .= "<5800> <58ff> <5800>\n";
9776: $stream .= "<5900> <59ff> <5900>\n";
9777: $stream .= "<5a00> <5aff> <5a00>\n";
9778: $stream .= "<5b00> <5bff> <5b00>\n";
9779: $stream .= "<5c00> <5cff> <5c00>\n";
9780: $stream .= "<5d00> <5dff> <5d00>\n";
9781: $stream .= "<5e00> <5eff> <5e00>\n";
9782: $stream .= "<5f00> <5fff> <5f00>\n";
9783: $stream .= "<6000> <60ff> <6000>\n";
9784: $stream .= "<6100> <61ff> <6100>\n";
9785: $stream .= "<6200> <62ff> <6200>\n";
9786: $stream .= "<6300> <63ff> <6300>\n";
9787: $stream .= "endbfrange\n";
9788: $stream .= "100 beginbfrange\n";
9789: $stream .= "<6400> <64ff> <6400>\n";
9790: $stream .= "<6500> <65ff> <6500>\n";
9791: $stream .= "<6600> <66ff> <6600>\n";
9792: $stream .= "<6700> <67ff> <6700>\n";
9793: $stream .= "<6800> <68ff> <6800>\n";
9794: $stream .= "<6900> <69ff> <6900>\n";
9795: $stream .= "<6a00> <6aff> <6a00>\n";
9796: $stream .= "<6b00> <6bff> <6b00>\n";
9797: $stream .= "<6c00> <6cff> <6c00>\n";
9798: $stream .= "<6d00> <6dff> <6d00>\n";
9799: $stream .= "<6e00> <6eff> <6e00>\n";
9800: $stream .= "<6f00> <6fff> <6f00>\n";
9801: $stream .= "<7000> <70ff> <7000>\n";
9802: $stream .= "<7100> <71ff> <7100>\n";
9803: $stream .= "<7200> <72ff> <7200>\n";
9804: $stream .= "<7300> <73ff> <7300>\n";
9805: $stream .= "<7400> <74ff> <7400>\n";
9806: $stream .= "<7500> <75ff> <7500>\n";
9807: $stream .= "<7600> <76ff> <7600>\n";
9808: $stream .= "<7700> <77ff> <7700>\n";
9809: $stream .= "<7800> <78ff> <7800>\n";
9810: $stream .= "<7900> <79ff> <7900>\n";
9811: $stream .= "<7a00> <7aff> <7a00>\n";
9812: $stream .= "<7b00> <7bff> <7b00>\n";
9813: $stream .= "<7c00> <7cff> <7c00>\n";
9814: $stream .= "<7d00> <7dff> <7d00>\n";
9815: $stream .= "<7e00> <7eff> <7e00>\n";
9816: $stream .= "<7f00> <7fff> <7f00>\n";
9817: $stream .= "<8000> <80ff> <8000>\n";
9818: $stream .= "<8100> <81ff> <8100>\n";
9819: $stream .= "<8200> <82ff> <8200>\n";
9820: $stream .= "<8300> <83ff> <8300>\n";
9821: $stream .= "<8400> <84ff> <8400>\n";
9822: $stream .= "<8500> <85ff> <8500>\n";
9823: $stream .= "<8600> <86ff> <8600>\n";
9824: $stream .= "<8700> <87ff> <8700>\n";
9825: $stream .= "<8800> <88ff> <8800>\n";
9826: $stream .= "<8900> <89ff> <8900>\n";
9827: $stream .= "<8a00> <8aff> <8a00>\n";
9828: $stream .= "<8b00> <8bff> <8b00>\n";
9829: $stream .= "<8c00> <8cff> <8c00>\n";
9830: $stream .= "<8d00> <8dff> <8d00>\n";
9831: $stream .= "<8e00> <8eff> <8e00>\n";
9832: $stream .= "<8f00> <8fff> <8f00>\n";
9833: $stream .= "<9000> <90ff> <9000>\n";
9834: $stream .= "<9100> <91ff> <9100>\n";
9835: $stream .= "<9200> <92ff> <9200>\n";
9836: $stream .= "<9300> <93ff> <9300>\n";
9837: $stream .= "<9400> <94ff> <9400>\n";
9838: $stream .= "<9500> <95ff> <9500>\n";
9839: $stream .= "<9600> <96ff> <9600>\n";
9840: $stream .= "<9700> <97ff> <9700>\n";
9841: $stream .= "<9800> <98ff> <9800>\n";
9842: $stream .= "<9900> <99ff> <9900>\n";
9843: $stream .= "<9a00> <9aff> <9a00>\n";
9844: $stream .= "<9b00> <9bff> <9b00>\n";
9845: $stream .= "<9c00> <9cff> <9c00>\n";
9846: $stream .= "<9d00> <9dff> <9d00>\n";
9847: $stream .= "<9e00> <9eff> <9e00>\n";
9848: $stream .= "<9f00> <9fff> <9f00>\n";
9849: $stream .= "<a000> <a0ff> <a000>\n";
9850: $stream .= "<a100> <a1ff> <a100>\n";
9851: $stream .= "<a200> <a2ff> <a200>\n";
9852: $stream .= "<a300> <a3ff> <a300>\n";
9853: $stream .= "<a400> <a4ff> <a400>\n";
9854: $stream .= "<a500> <a5ff> <a500>\n";
9855: $stream .= "<a600> <a6ff> <a600>\n";
9856: $stream .= "<a700> <a7ff> <a700>\n";
9857: $stream .= "<a800> <a8ff> <a800>\n";
9858: $stream .= "<a900> <a9ff> <a900>\n";
9859: $stream .= "<aa00> <aaff> <aa00>\n";
9860: $stream .= "<ab00> <abff> <ab00>\n";
9861: $stream .= "<ac00> <acff> <ac00>\n";
9862: $stream .= "<ad00> <adff> <ad00>\n";
9863: $stream .= "<ae00> <aeff> <ae00>\n";
9864: $stream .= "<af00> <afff> <af00>\n";
9865: $stream .= "<b000> <b0ff> <b000>\n";
9866: $stream .= "<b100> <b1ff> <b100>\n";
9867: $stream .= "<b200> <b2ff> <b200>\n";
9868: $stream .= "<b300> <b3ff> <b300>\n";
9869: $stream .= "<b400> <b4ff> <b400>\n";
9870: $stream .= "<b500> <b5ff> <b500>\n";
9871: $stream .= "<b600> <b6ff> <b600>\n";
9872: $stream .= "<b700> <b7ff> <b700>\n";
9873: $stream .= "<b800> <b8ff> <b800>\n";
9874: $stream .= "<b900> <b9ff> <b900>\n";
9875: $stream .= "<ba00> <baff> <ba00>\n";
9876: $stream .= "<bb00> <bbff> <bb00>\n";
9877: $stream .= "<bc00> <bcff> <bc00>\n";
9878: $stream .= "<bd00> <bdff> <bd00>\n";
9879: $stream .= "<be00> <beff> <be00>\n";
9880: $stream .= "<bf00> <bfff> <bf00>\n";
9881: $stream .= "<c000> <c0ff> <c000>\n";
9882: $stream .= "<c100> <c1ff> <c100>\n";
9883: $stream .= "<c200> <c2ff> <c200>\n";
9884: $stream .= "<c300> <c3ff> <c300>\n";
9885: $stream .= "<c400> <c4ff> <c400>\n";
9886: $stream .= "<c500> <c5ff> <c500>\n";
9887: $stream .= "<c600> <c6ff> <c600>\n";
9888: $stream .= "<c700> <c7ff> <c700>\n";
9889: $stream .= "endbfrange\n";
9890: $stream .= "56 beginbfrange\n";
9891: $stream .= "<c800> <c8ff> <c800>\n";
9892: $stream .= "<c900> <c9ff> <c900>\n";
9893: $stream .= "<ca00> <caff> <ca00>\n";
9894: $stream .= "<cb00> <cbff> <cb00>\n";
9895: $stream .= "<cc00> <ccff> <cc00>\n";
9896: $stream .= "<cd00> <cdff> <cd00>\n";
9897: $stream .= "<ce00> <ceff> <ce00>\n";
9898: $stream .= "<cf00> <cfff> <cf00>\n";
9899: $stream .= "<d000> <d0ff> <d000>\n";
9900: $stream .= "<d100> <d1ff> <d100>\n";
9901: $stream .= "<d200> <d2ff> <d200>\n";
9902: $stream .= "<d300> <d3ff> <d300>\n";
9903: $stream .= "<d400> <d4ff> <d400>\n";
9904: $stream .= "<d500> <d5ff> <d500>\n";
9905: $stream .= "<d600> <d6ff> <d600>\n";
9906: $stream .= "<d700> <d7ff> <d700>\n";
9907: $stream .= "<d800> <d8ff> <d800>\n";
9908: $stream .= "<d900> <d9ff> <d900>\n";
9909: $stream .= "<da00> <daff> <da00>\n";
9910: $stream .= "<db00> <dbff> <db00>\n";
9911: $stream .= "<dc00> <dcff> <dc00>\n";
9912: $stream .= "<dd00> <ddff> <dd00>\n";
9913: $stream .= "<de00> <deff> <de00>\n";
9914: $stream .= "<df00> <dfff> <df00>\n";
9915: $stream .= "<e000> <e0ff> <e000>\n";
9916: $stream .= "<e100> <e1ff> <e100>\n";
9917: $stream .= "<e200> <e2ff> <e200>\n";
9918: $stream .= "<e300> <e3ff> <e300>\n";
9919: $stream .= "<e400> <e4ff> <e400>\n";
9920: $stream .= "<e500> <e5ff> <e500>\n";
9921: $stream .= "<e600> <e6ff> <e600>\n";
9922: $stream .= "<e700> <e7ff> <e700>\n";
9923: $stream .= "<e800> <e8ff> <e800>\n";
9924: $stream .= "<e900> <e9ff> <e900>\n";
9925: $stream .= "<ea00> <eaff> <ea00>\n";
9926: $stream .= "<eb00> <ebff> <eb00>\n";
9927: $stream .= "<ec00> <ecff> <ec00>\n";
9928: $stream .= "<ed00> <edff> <ed00>\n";
9929: $stream .= "<ee00> <eeff> <ee00>\n";
9930: $stream .= "<ef00> <efff> <ef00>\n";
9931: $stream .= "<f000> <f0ff> <f000>\n";
9932: $stream .= "<f100> <f1ff> <f100>\n";
9933: $stream .= "<f200> <f2ff> <f200>\n";
9934: $stream .= "<f300> <f3ff> <f300>\n";
9935: $stream .= "<f400> <f4ff> <f400>\n";
9936: $stream .= "<f500> <f5ff> <f500>\n";
9937: $stream .= "<f600> <f6ff> <f600>\n";
9938: $stream .= "<f700> <f7ff> <f700>\n";
9939: $stream .= "<f800> <f8ff> <f800>\n";
9940: $stream .= "<f900> <f9ff> <f900>\n";
9941: $stream .= "<fa00> <faff> <fa00>\n";
9942: $stream .= "<fb00> <fbff> <fb00>\n";
9943: $stream .= "<fc00> <fcff> <fc00>\n";
9944: $stream .= "<fd00> <fdff> <fd00>\n";
9945: $stream .= "<fe00> <feff> <fe00>\n";
9946: $stream .= "<ff00> <ffff> <ff00>\n";
9947: $stream .= "endbfrange\n";
9948: $stream .= "endcmap\n";
9949: $stream .= "CMapName currentdict /CMap defineresource pop\n";
9950: $stream .= "end\n";
9951: $stream .= "end";
9952:
9953: $this->_newobj();
9954: $stream = ($this->compress) ? gzcompress($stream) : $stream;
9955: $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
9956: $stream = $this->_getrawstream($stream);
9957: $this->_out('<<'.$filter.'/Length '.strlen($stream).'>> stream'."\n".$stream."\n".'endstream'."\n".'endobj');
9958:
9959:
9960: $oid = $this->_newobj();
9961: $out = '<< /Type /Font';
9962: $out .= ' /Subtype /CIDFontType2';
9963: $out .= ' /BaseFont /'.$fontname;
9964:
9965: $cidinfo = '/Registry '.$this->_datastring($font['cidinfo']['Registry'], $oid);
9966: $cidinfo .= ' /Ordering '.$this->_datastring($font['cidinfo']['Ordering'], $oid);
9967: $cidinfo .= ' /Supplement '.$font['cidinfo']['Supplement'];
9968: $out .= ' /CIDSystemInfo << '.$cidinfo.' >>';
9969: $out .= ' /FontDescriptor '.($this->n + 1).' 0 R';
9970: $out .= ' /DW '.$font['dw'];
9971: $out .= "\n".$this->_putfontwidths($font, 0);
9972: if (isset($font['ctg']) AND (!$this->empty_string($font['ctg']))) {
9973: $out .= "\n".'/CIDToGIDMap '.($this->n + 2).' 0 R';
9974: }
9975: $out .= ' >>';
9976: $out .= "\n".'endobj';
9977: $this->_out($out);
9978:
9979:
9980: $this->_newobj();
9981: $out = '<< /Type /FontDescriptor';
9982: $out .= ' /FontName /'.$fontname;
9983: foreach ($font['desc'] as $key => $value) {
9984: if(is_float($value)) {
9985: $value = sprintf('%.3F', $value);
9986: }
9987: $out .= ' /'.$key.' '.$value;
9988: }
9989: $fontdir = false;
9990: if (!$this->empty_string($font['file'])) {
9991:
9992: $out .= ' /FontFile2 '.$this->FontFiles[$font['file']]['n'].' 0 R';
9993: $fontdir = $this->FontFiles[$font['file']]['fontdir'];
9994: }
9995: $out .= ' >>';
9996: $out .= "\n".'endobj';
9997: $this->_out($out);
9998: if (isset($font['ctg']) AND (!$this->empty_string($font['ctg']))) {
9999: $this->_newobj();
10000:
10001:
10002:
10003: $ctgfile = strtolower($font['ctg']);
10004:
10005: $fontfile = '';
10006:
10007: if (($fontdir !== false) AND file_exists($fontdir.$ctgfile)) {
10008: $fontfile = $fontdir.$ctgfile;
10009: } elseif (file_exists($this->_getfontpath().$ctgfile)) {
10010: $fontfile = $this->_getfontpath().$ctgfile;
10011: } elseif (file_exists($ctgfile)) {
10012: $fontfile = $ctgfile;
10013: }
10014: if ($this->empty_string($fontfile)) {
10015: $this->Error('Font file not found: '.$ctgfile);
10016: }
10017: $stream = $this->_getrawstream(file_get_contents($fontfile));
10018: $out = '<< /Length '.strlen($stream).'';
10019: if (substr($fontfile, -2) == '.z') {
10020:
10021:
10022:
10023: $out .= ' /Filter /FlateDecode';
10024: }
10025: $out .= ' >>';
10026: $out .= ' stream'."\n".$stream."\n".'endstream';
10027: $out .= "\n".'endobj';
10028: $this->_out($out);
10029: }
10030: }
10031:
10032: 10033: 10034: 10035: 10036: 10037: 10038: 10039:
10040: protected function _putcidfont0($font) {
10041: $cidoffset = 0;
10042: if (!isset($font['cw'][1])) {
10043: $cidoffset = 31;
10044: }
10045: if (isset($font['cidinfo']['uni2cid'])) {
10046:
10047: $uni2cid = $font['cidinfo']['uni2cid'];
10048: $cw = array();
10049: foreach ($font['cw'] as $uni => $width) {
10050: if (isset($uni2cid[$uni])) {
10051: $cw[($uni2cid[$uni] + $cidoffset)] = $width;
10052: } elseif ($uni < 256) {
10053: $cw[$uni] = $width;
10054: }
10055: }
10056: $font = array_merge($font, array('cw' => $cw));
10057: }
10058: $name = $font['name'];
10059: $enc = $font['enc'];
10060: if ($enc) {
10061: $longname = $name.'-'.$enc;
10062: } else {
10063: $longname = $name;
10064: }
10065: $out = $this->_getobj($this->font_obj_ids[$font['fontkey']])."\n";
10066: $out .= '<</Type /Font';
10067: $out .= ' /Subtype /Type0';
10068: $out .= ' /BaseFont /'.$longname;
10069: $out .= ' /Name /F'.$font['i'];
10070: if ($enc) {
10071: $out .= ' /Encoding /'.$enc;
10072: }
10073: $out .= ' /DescendantFonts ['.($this->n + 1).' 0 R]';
10074: $out .= ' >>';
10075: $out .= "\n".'endobj';
10076: $this->_out($out);
10077: $oid = $this->_newobj();
10078: $out = '<</Type /Font';
10079: $out .= ' /Subtype /CIDFontType0';
10080: $out .= ' /BaseFont /'.$name;
10081: $cidinfo = '/Registry '.$this->_datastring($font['cidinfo']['Registry'], $oid);
10082: $cidinfo .= ' /Ordering '.$this->_datastring($font['cidinfo']['Ordering'], $oid);
10083: $cidinfo .= ' /Supplement '.$font['cidinfo']['Supplement'];
10084: $out .= ' /CIDSystemInfo <<'.$cidinfo.'>>';
10085: $out .= ' /FontDescriptor '.($this->n + 1).' 0 R';
10086: $out .= ' /DW '.$font['dw'];
10087: $out .= "\n".$this->_putfontwidths($font, $cidoffset);
10088: $out .= ' >>';
10089: $out .= "\n".'endobj';
10090: $this->_out($out);
10091: $this->_newobj();
10092: $s = '<</Type /FontDescriptor /FontName /'.$name;
10093: foreach ($font['desc'] as $k => $v) {
10094: if ($k != 'Style') {
10095: if(is_float($v)) {
10096: $v = sprintf('%.3F', $v);
10097: }
10098: $s .= ' /'.$k.' '.$v.'';
10099: }
10100: }
10101: $s .= '>>';
10102: $s .= "\n".'endobj';
10103: $this->_out($s);
10104: }
10105:
10106: 10107: 10108: 10109:
10110: protected function _putimages() {
10111: $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
10112: foreach ($this->imagekeys as $file) {
10113: $info = $this->getImageBuffer($file);
10114: $oid = $this->_newobj();
10115: $this->xobjects['I'.$info['i']] = array('n' => $oid);
10116: $this->setImageSubBuffer($file, 'n', $this->n);
10117: $out = '<</Type /XObject';
10118: $out .= ' /Subtype /Image';
10119: $out .= ' /Width '.$info['w'];
10120: $out .= ' /Height '.$info['h'];
10121: if (array_key_exists('masked', $info)) {
10122: $out .= ' /SMask '.($this->n - 1).' 0 R';
10123: }
10124: if ($info['cs'] == 'Indexed') {
10125: $out .= ' /ColorSpace [/Indexed /DeviceRGB '.((strlen($info['pal']) / 3) - 1).' '.($this->n + 1).' 0 R]';
10126: } else {
10127: $out .= ' /ColorSpace /'.$info['cs'];
10128: if ($info['cs'] == 'DeviceCMYK') {
10129: $out .= ' /Decode [1 0 1 0 1 0 1 0]';
10130: }
10131: }
10132: $out .= ' /BitsPerComponent '.$info['bpc'];
10133: if (isset($info['f'])) {
10134: $out .= ' /Filter /'.$info['f'];
10135: }
10136: if (isset($info['parms'])) {
10137: $out .= ' '.$info['parms'];
10138: }
10139: if (isset($info['trns']) AND is_array($info['trns'])) {
10140: $trns='';
10141: $count_info = count($info['trns']);
10142: for ($i=0; $i < $count_info; ++$i) {
10143: $trns .= $info['trns'][$i].' '.$info['trns'][$i].' ';
10144: }
10145: $out .= ' /Mask ['.$trns.']';
10146: }
10147: $stream = $this->_getrawstream($info['data']);
10148: $out .= ' /Length '.strlen($stream).' >>';
10149: $out .= ' stream'."\n".$stream."\n".'endstream';
10150: $out .= "\n".'endobj';
10151: $this->_out($out);
10152:
10153: if ($info['cs'] == 'Indexed') {
10154: $this->_newobj();
10155: $pal = ($this->compress) ? gzcompress($info['pal']) : $info['pal'];
10156: $pal = $this->_getrawstream($pal);
10157: $this->_out('<<'.$filter.'/Length '.strlen($pal).'>> stream'."\n".$pal."\n".'endstream'."\n".'endobj');
10158: }
10159: }
10160: }
10161:
10162: 10163: 10164: 10165: 10166: 10167: 10168:
10169: protected function _putxobjects() {
10170: foreach ($this->xobjects as $key => $data) {
10171: if (isset($data['outdata'])) {
10172: $stream = trim($data['outdata']);
10173: $out = $this->_getobj($data['n'])."\n";
10174: $out .= '<<';
10175: $out .= ' /Type /XObject';
10176: $out .= ' /Subtype /Form';
10177: $out .= ' /FormType 1';
10178: if ($this->compress) {
10179: $stream = gzcompress($stream);
10180: $out .= ' /Filter /FlateDecode';
10181: }
10182: $out .= sprintf(' /BBox [%.2F %.2F %.2F %.2F]', ($data['x'] * $this->k), (-$data['y'] * $this->k), (($data['w'] + $data['x']) * $this->k), (($data['h'] - $data['y']) * $this->k));
10183: $out .= ' /Matrix [1 0 0 1 0 0]';
10184: $out .= ' /Resources <<';
10185: $out .= ' /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]';
10186:
10187: if (!empty($data['fonts'])) {
10188: $out .= ' /Font <<';
10189: foreach ($data['fonts'] as $fontkey => $fontid) {
10190: $out .= ' /F'.$fontid.' '.$this->font_obj_ids[$fontkey].' 0 R';
10191: }
10192: $out .= ' >>';
10193: }
10194:
10195: if (!empty($data['images']) OR !empty($data['xobjects'])) {
10196: $out .= ' /XObject <<';
10197: foreach ($data['images'] as $imgid) {
10198: $out .= ' /I'.$imgid.' '.$this->xobjects['I'.$imgid]['n'].' 0 R';
10199: }
10200: foreach ($data['xobjects'] as $sub_id => $sub_objid) {
10201: $out .= ' /'.$sub_id.' '.$sub_objid['n'].' 0 R';
10202: }
10203: $out .= ' >>';
10204: }
10205: $out .= ' >>';
10206: $stream = $this->_getrawstream($stream);
10207: $out .= ' /Length '.strlen($stream);
10208: $out .= ' >>';
10209: $out .= ' stream'."\n".$stream."\n".'endstream';
10210: $out .= "\n".'endobj';
10211: $this->_out($out);
10212: }
10213: }
10214: }
10215:
10216: 10217: 10218: 10219: 10220:
10221: protected function _putspotcolors() {
10222: foreach ($this->spot_colors as $name => $color) {
10223: $this->_newobj();
10224: $this->spot_colors[$name]['n'] = $this->n;
10225: $out = '[/Separation /'.str_replace(' ', '#20', $name);
10226: $out .= ' /DeviceCMYK <<';
10227: $out .= ' /Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0]';
10228: $out .= ' '.sprintf('/C1 [%.4F %.4F %.4F %.4F] ', $color['c']/100, $color['m']/100, $color['y']/100, $color['k']/100);
10229: $out .= ' /FunctionType 2 /Domain [0 1] /N 1>>]';
10230: $out .= "\n".'endobj';
10231: $this->_out($out);
10232: }
10233: }
10234:
10235: 10236: 10237: 10238: 10239: 10240:
10241: protected function _getxobjectdict() {
10242: $out = '';
10243: foreach ($this->xobjects as $id => $objid) {
10244: $out .= ' /'.$id.' '.$objid['n'].' 0 R';
10245: }
10246: return $out;
10247: }
10248:
10249: 10250: 10251: 10252:
10253: protected function _putresourcedict() {
10254: $out = $this->_getobj(2)."\n";
10255: $out .= '<< /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]';
10256: $out .= ' /Font <<';
10257: foreach ($this->fontkeys as $fontkey) {
10258: $font = $this->getFontBuffer($fontkey);
10259: $out .= ' /F'.$font['i'].' '.$font['n'].' 0 R';
10260: }
10261: $out .= ' >>';
10262: $out .= ' /XObject <<';
10263: $out .= $this->_getxobjectdict();
10264: $out .= ' >>';
10265:
10266: $out .= ' /Properties <</OC1 '.$this->n_ocg_print.' 0 R /OC2 '.$this->n_ocg_view.' 0 R>>';
10267:
10268: $out .= ' /ExtGState <<';
10269: foreach ($this->extgstates as $k => $extgstate) {
10270: if (isset($extgstate['name'])) {
10271: $out .= ' /'.$extgstate['name'];
10272: } else {
10273: $out .= ' /GS'.$k;
10274: }
10275: $out .= ' '.$extgstate['n'].' 0 R';
10276: }
10277: $out .= ' >>';
10278:
10279: if (isset($this->gradients) AND (count($this->gradients) > 0)) {
10280: $out .= ' /Pattern <<';
10281: foreach ($this->gradients as $id => $grad) {
10282: $out .= ' /p'.$id.' '.$grad['pattern'].' 0 R';
10283: }
10284: $out .= ' >>';
10285: }
10286:
10287: if (isset($this->gradients) AND (count($this->gradients) > 0)) {
10288: $out .= ' /Shading <<';
10289: foreach ($this->gradients as $id => $grad) {
10290: $out .= ' /Sh'.$id.' '.$grad['id'].' 0 R';
10291: }
10292: $out .= ' >>';
10293: }
10294:
10295: if (isset($this->spot_colors) AND (count($this->spot_colors) > 0)) {
10296: $out .= ' /ColorSpace <<';
10297: foreach ($this->spot_colors as $color) {
10298: $out .= ' /CS'.$color['i'].' '.$color['n'].' 0 R';
10299: }
10300: $out .= ' >>';
10301: }
10302: $out .= ' >>';
10303: $out .= "\n".'endobj';
10304: $this->_out($out);
10305: }
10306:
10307: 10308: 10309: 10310:
10311: protected function _putresources() {
10312: $this->_putextgstates();
10313: $this->_putocg();
10314: $this->_putfonts();
10315: $this->_putimages();
10316: $this->_putxobjects();
10317: $this->_putspotcolors();
10318: $this->_putshaders();
10319: $this->_putresourcedict();
10320: $this->_putbookmarks();
10321: $this->_putEmbeddedFiles();
10322: $this->_putannotsobjs();
10323: $this->_putjavascript();
10324: $this->_putencryption();
10325: }
10326:
10327: 10328: 10329: 10330: 10331: 10332:
10333: protected function _putinfo() {
10334: $oid = $this->_newobj();
10335: $out = '<<';
10336: if (!$this->empty_string($this->title)) {
10337:
10338: $out .= ' /Title '.$this->_textstring($this->title, $oid);
10339: }
10340: if (!$this->empty_string($this->author)) {
10341:
10342: $out .= ' /Author '.$this->_textstring($this->author, $oid);
10343: }
10344: if (!$this->empty_string($this->subject)) {
10345:
10346: $out .= ' /Subject '.$this->_textstring($this->subject, $oid);
10347: }
10348: if (!$this->empty_string($this->keywords)) {
10349:
10350: $out .= ' /Keywords '.$this->_textstring($this->keywords.' TCP'.'DF', $oid);
10351: }
10352: if (!$this->empty_string($this->creator)) {
10353:
10354: $out .= ' /Creator '.$this->_textstring($this->creator, $oid);
10355: }
10356: if (defined('PDF_PRODUCER')) {
10357:
10358: $out .= ' /Producer '.$this->_textstring(PDF_PRODUCER.' (TCP'.'DF)', $oid);
10359: } else {
10360:
10361: $out .= ' /Producer '.$this->_textstring('TCP'.'DF', $oid);
10362: }
10363:
10364: $out .= ' /CreationDate '.$this->_datestring();
10365:
10366: $out .= ' /ModDate '.$this->_datestring();
10367:
10368: $out .= ' /Trapped /False';
10369: $out .= ' >>';
10370: $out .= "\n".'endobj';
10371: $this->_out($out);
10372: return $oid;
10373: }
10374:
10375: 10376: 10377: 10378: 10379:
10380: protected function _putcatalog() {
10381: $oid = $this->_newobj();
10382: $out = '<< /Type /Catalog';
10383: $out .= ' /Pages 1 0 R';
10384: if ($this->ZoomMode == 'fullpage') {
10385: $out .= ' /OpenAction ['.$this->page_obj_id[1].' 0 R /Fit]';
10386: } elseif ($this->ZoomMode == 'fullwidth') {
10387: $out .= ' /OpenAction ['.$this->page_obj_id[1].' 0 R /FitH null]';
10388: } elseif ($this->ZoomMode == 'real') {
10389: $out .= ' /OpenAction ['.$this->page_obj_id[1].' 0 R /XYZ null null 1]';
10390: } elseif (!is_string($this->ZoomMode)) {
10391: $out .= sprintf(' /OpenAction ['.$this->page_obj_id[1].' 0 R /XYZ null null %.2F]',($this->ZoomMode / 100));
10392: }
10393: if (isset($this->LayoutMode) AND (!$this->empty_string($this->LayoutMode))) {
10394: $out .= ' /PageLayout /'.$this->LayoutMode;
10395: }
10396: if (isset($this->PageMode) AND (!$this->empty_string($this->PageMode))) {
10397: $out .= ' /PageMode /'.$this->PageMode;
10398: }
10399: if (isset($this->l['a_meta_language'])) {
10400: $out .= ' /Lang '.$this->_textstring($this->l['a_meta_language'], $oid);
10401: }
10402: $out .= ' /Names <<';
10403: if ((!empty($this->javascript)) OR (!empty($this->js_objects))) {
10404: $out .= ' /JavaScript '.($this->n_js).' 0 R';
10405: }
10406: $out .= ' >>';
10407: if (count($this->outlines) > 0) {
10408: $out .= ' /Outlines '.$this->OutlineRoot.' 0 R';
10409: $out .= ' /PageMode /UseOutlines';
10410: }
10411: $out .= ' '.$this->_putviewerpreferences();
10412: $p = $this->n_ocg_print.' 0 R';
10413: $v = $this->n_ocg_view.' 0 R';
10414: $as = '<< /Event /Print /OCGs ['.$p.' '.$v.'] /Category [/Print] >> << /Event /View /OCGs ['.$p.' '.$v.'] /Category [/View] >>';
10415: $out .= ' /OCProperties << /OCGs ['.$p.' '.$v.'] /D << /ON ['.$p.'] /OFF ['.$v.'] /AS ['.$as.'] >> >>';
10416:
10417: if (!empty($this->form_obj_id) OR ($this->sign AND isset($this->signature_data['cert_type']))) {
10418: $out .= ' /AcroForm <<';
10419: $objrefs = '';
10420: if ($this->sign AND isset($this->signature_data['cert_type'])) {
10421: $objrefs .= $this->sig_obj_id.' 0 R';
10422: }
10423: if (!empty($this->form_obj_id)) {
10424: foreach($this->form_obj_id as $objid) {
10425: $objrefs .= ' '.$objid.' 0 R';
10426: }
10427: }
10428: $out .= ' /Fields ['.$objrefs.']';
10429: if (!empty($this->form_obj_id) AND !$this->sign) {
10430:
10431: $out .= ' /NeedAppearances true';
10432: }
10433: if ($this->sign AND isset($this->signature_data['cert_type'])) {
10434: if ($this->signature_data['cert_type'] > 0) {
10435: $out .= ' /SigFlags 3';
10436: } else {
10437: $out .= ' /SigFlags 1';
10438: }
10439: }
10440:
10441: if (isset($this->annotation_fonts) AND !empty($this->annotation_fonts)) {
10442: $out .= ' /DR <<';
10443: $out .= ' /Font <<';
10444: foreach ($this->annotation_fonts as $fontkey => $fontid) {
10445: $out .= ' /F'.$fontid.' '.$this->font_obj_ids[$fontkey].' 0 R';
10446: }
10447: $out .= ' >> >>';
10448: }
10449: $font = $this->getFontBuffer('helvetica');
10450: $out .= ' /DA (/F'.$font['i'].' 0 Tf 0 g)';
10451: $out .= ' /Q '.(($this->rtl)?'2':'0');
10452:
10453: $out .= ' >>';
10454:
10455: if ($this->sign AND isset($this->signature_data['cert_type'])) {
10456: if ($this->signature_data['cert_type'] > 0) {
10457: $out .= ' /Perms << /DocMDP '.($this->sig_obj_id + 1).' 0 R >>';
10458: } else {
10459: $out .= ' /Perms << /UR3 '.($this->sig_obj_id + 1).' 0 R >>';
10460: }
10461: }
10462: }
10463: $out .= ' >>';
10464: $out .= "\n".'endobj';
10465: $this->_out($out);
10466: return $oid;
10467: }
10468:
10469: 10470: 10471: 10472: 10473: 10474: 10475:
10476: protected function _putviewerpreferences() {
10477: $out = '/ViewerPreferences <<';
10478: if ($this->rtl) {
10479: $out .= ' /Direction /R2L';
10480: } else {
10481: $out .= ' /Direction /L2R';
10482: }
10483: if (isset($this->viewer_preferences['HideToolbar']) AND ($this->viewer_preferences['HideToolbar'])) {
10484: $out .= ' /HideToolbar true';
10485: }
10486: if (isset($this->viewer_preferences['HideMenubar']) AND ($this->viewer_preferences['HideMenubar'])) {
10487: $out .= ' /HideMenubar true';
10488: }
10489: if (isset($this->viewer_preferences['HideWindowUI']) AND ($this->viewer_preferences['HideWindowUI'])) {
10490: $out .= ' /HideWindowUI true';
10491: }
10492: if (isset($this->viewer_preferences['FitWindow']) AND ($this->viewer_preferences['FitWindow'])) {
10493: $out .= ' /FitWindow true';
10494: }
10495: if (isset($this->viewer_preferences['CenterWindow']) AND ($this->viewer_preferences['CenterWindow'])) {
10496: $out .= ' /CenterWindow true';
10497: }
10498: if (isset($this->viewer_preferences['DisplayDocTitle']) AND ($this->viewer_preferences['DisplayDocTitle'])) {
10499: $out .= ' /DisplayDocTitle true';
10500: }
10501: if (isset($this->viewer_preferences['NonFullScreenPageMode'])) {
10502: $out .= ' /NonFullScreenPageMode /'.$this->viewer_preferences['NonFullScreenPageMode'];
10503: }
10504: if (isset($this->viewer_preferences['ViewArea'])) {
10505: $out .= ' /ViewArea /'.$this->viewer_preferences['ViewArea'];
10506: }
10507: if (isset($this->viewer_preferences['ViewClip'])) {
10508: $out .= ' /ViewClip /'.$this->viewer_preferences['ViewClip'];
10509: }
10510: if (isset($this->viewer_preferences['PrintArea'])) {
10511: $out .= ' /PrintArea /'.$this->viewer_preferences['PrintArea'];
10512: }
10513: if (isset($this->viewer_preferences['PrintClip'])) {
10514: $out .= ' /PrintClip /'.$this->viewer_preferences['PrintClip'];
10515: }
10516: if (isset($this->viewer_preferences['PrintScaling'])) {
10517: $out .= ' /PrintScaling /'.$this->viewer_preferences['PrintScaling'];
10518: }
10519: if (isset($this->viewer_preferences['Duplex']) AND (!$this->empty_string($this->viewer_preferences['Duplex']))) {
10520: $out .= ' /Duplex /'.$this->viewer_preferences['Duplex'];
10521: }
10522: if (isset($this->viewer_preferences['PickTrayByPDFSize'])) {
10523: if ($this->viewer_preferences['PickTrayByPDFSize']) {
10524: $out .= ' /PickTrayByPDFSize true';
10525: } else {
10526: $out .= ' /PickTrayByPDFSize false';
10527: }
10528: }
10529: if (isset($this->viewer_preferences['PrintPageRange'])) {
10530: $PrintPageRangeNum = '';
10531: foreach ($this->viewer_preferences['PrintPageRange'] as $k => $v) {
10532: $PrintPageRangeNum .= ' '.($v - 1).'';
10533: }
10534: $out .= ' /PrintPageRange ['.substr($PrintPageRangeNum,1).']';
10535: }
10536: if (isset($this->viewer_preferences['NumCopies'])) {
10537: $out .= ' /NumCopies '.intval($this->viewer_preferences['NumCopies']);
10538: }
10539: $out .= ' >>';
10540: return $out;
10541: }
10542:
10543: 10544: 10545: 10546:
10547: protected function () {
10548: $this->_out('%PDF-'.$this->PDFVersion);
10549: }
10550:
10551: 10552: 10553: 10554:
10555: protected function _enddoc() {
10556: $this->state = 1;
10557: $this->_putheader();
10558: $this->_putpages();
10559: $this->_putresources();
10560:
10561: if ($this->sign AND isset($this->signature_data['cert_type'])) {
10562:
10563: $out = $this->_getobj($this->sig_obj_id)."\n";
10564: $out .= '<< /Type /Annot';
10565: $out .= ' /Subtype /Widget';
10566: $out .= ' /Rect ['.$this->signature_appearance['rect'].']';
10567: $out .= ' /P '.$this->page_obj_id[($this->signature_appearance['page'])].' 0 R';
10568: $out .= ' /F 4';
10569: $out .= ' /FT /Sig';
10570: $out .= ' /T '.$this->_textstring('Signature', $this->sig_obj_id);
10571: $out .= ' /Ff 0';
10572: $out .= ' /V '.($this->sig_obj_id + 1).' 0 R';
10573: $out .= ' >>';
10574: $out .= "\n".'endobj';
10575: $this->_out($out);
10576:
10577: $this->_putsignature();
10578: }
10579:
10580: $objid_info = $this->_putinfo();
10581:
10582: $objid_catalog = $this->_putcatalog();
10583:
10584: $o = $this->bufferlen;
10585:
10586: $this->_out('xref');
10587: $this->_out('0 '.($this->n + 1));
10588: $this->_out('0000000000 65535 f ');
10589: for ($i=1; $i <= $this->n; ++$i) {
10590: $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i]));
10591: }
10592:
10593: $out = 'trailer <<';
10594: $out .= ' /Size '.($this->n + 1);
10595: $out .= ' /Root '.$objid_catalog.' 0 R';
10596: $out .= ' /Info '.$objid_info.' 0 R';
10597: if ($this->encrypted) {
10598: $out .= ' /Encrypt '.$this->encryptdata['objid'].' 0 R';
10599: }
10600: $out .= ' /ID [ <'.$this->file_id.'> <'.$this->file_id.'> ]';
10601: $out .= ' >>';
10602: $this->_out($out);
10603: $this->_out('startxref');
10604: $this->_out($o);
10605: $this->_out('%%EOF');
10606: $this->state = 3;
10607: if ($this->diskcache) {
10608:
10609: foreach ($this->imagekeys as $key) {
10610:
10611: unlink($this->images[$key]);
10612: }
10613: foreach ($this->fontkeys as $key) {
10614:
10615: unlink($this->fonts[$key]);
10616: }
10617: }
10618: }
10619:
10620: 10621: 10622: 10623: 10624: 10625: 10626:
10627: protected function _beginpage($orientation='', $format='') {
10628: ++$this->page;
10629: $this->setPageBuffer($this->page, '');
10630:
10631: $this->transfmrk[$this->page] = array();
10632: $this->state = 2;
10633: if ($this->empty_string($orientation)) {
10634: if (isset($this->CurOrientation)) {
10635: $orientation = $this->CurOrientation;
10636: } elseif ($this->fwPt > $this->fhPt) {
10637:
10638: $orientation = 'L';
10639: } else {
10640:
10641: $orientation = 'P';
10642: }
10643: }
10644: if ($this->empty_string($format)) {
10645: $this->pagedim[$this->page] = $this->pagedim[($this->page - 1)];
10646: $this->setPageOrientation($orientation);
10647: } else {
10648: $this->setPageFormat($format, $orientation);
10649: }
10650: if ($this->rtl) {
10651: $this->x = $this->w - $this->rMargin;
10652: } else {
10653: $this->x = $this->lMargin;
10654: }
10655: $this->y = $this->tMargin;
10656: if (isset($this->newpagegroup[$this->page])) {
10657:
10658: $n = sizeof($this->pagegroups) + 1;
10659: $alias = '{nb'.$n.'}';
10660: $this->pagegroups[$alias] = 1;
10661: $this->currpagegroup = $alias;
10662: } elseif ($this->currpagegroup) {
10663: ++$this->pagegroups[$this->currpagegroup];
10664: }
10665: }
10666:
10667: 10668: 10669: 10670:
10671: protected function _endpage() {
10672: $this->setVisibility('all');
10673: $this->state = 1;
10674: }
10675:
10676: 10677: 10678: 10679: 10680:
10681: protected function _newobj() {
10682: $this->_out($this->_getobj());
10683: return $this->n;
10684: }
10685:
10686: 10687: 10688: 10689: 10690: 10691: 10692:
10693: protected function _getobj($objid='') {
10694: if ($objid === '') {
10695: ++$this->n;
10696: $objid = $this->n;
10697: }
10698: $this->offsets[$objid] = $this->bufferlen;
10699: return $objid.' 0 obj';
10700: }
10701:
10702: 10703: 10704: 10705: 10706: 10707: 10708:
10709: protected function _dounderline($x, $y, $txt) {
10710: $w = $this->GetStringWidth($txt);
10711: return $this->_dounderlinew($x, $y, $w);
10712: }
10713:
10714: 10715: 10716: 10717: 10718: 10719: 10720: 10721:
10722: protected function _dounderlinew($x, $y, $w) {
10723: $linew = - $this->CurrentFont['ut'] / 1000 * $this->FontSizePt;
10724: return sprintf('%.2F %.2F %.2F %.2F re f', $x * $this->k, ((($this->h - $y) * $this->k) + $linew), $w * $this->k, $linew);
10725: }
10726:
10727: 10728: 10729: 10730: 10731: 10732: 10733:
10734: protected function _dolinethrough($x, $y, $txt) {
10735: $w = $this->GetStringWidth($txt);
10736: return $this->_dolinethroughw($x, $y, $w);
10737: }
10738:
10739: 10740: 10741: 10742: 10743: 10744: 10745: 10746:
10747: protected function _dolinethroughw($x, $y, $w) {
10748: $linew = - $this->CurrentFont['ut'] / 1000 * $this->FontSizePt;
10749: return sprintf('%.2F %.2F %.2F %.2F re f', $x * $this->k, ((($this->h - $y) * $this->k) + $linew + ($this->FontSizePt / 3)), $w * $this->k, $linew);
10750: }
10751:
10752: 10753: 10754: 10755: 10756: 10757: 10758: 10759:
10760: protected function _dooverline($x, $y, $txt) {
10761: $w = $this->GetStringWidth($txt);
10762: return $this->_dooverlinew($x, $y, $w);
10763: }
10764:
10765: 10766: 10767: 10768: 10769: 10770: 10771: 10772:
10773: protected function _dooverlinew($x, $y, $w) {
10774: $linew = - $this->CurrentFont['ut'] / 1000 * $this->FontSizePt;
10775: return sprintf('%.2F %.2F %.2F %.2F re f', $x * $this->k, (($this->h - $y + $this->FontAscent) * $this->k) - $linew, $w * $this->k, $linew);
10776:
10777: }
10778:
10779: 10780: 10781: 10782: 10783: 10784:
10785: protected function _freadint($f) {
10786: $a = unpack('Ni', fread($f, 4));
10787: return $a['i'];
10788: }
10789:
10790: 10791: 10792: 10793: 10794: 10795:
10796: protected function _escape($s) {
10797:
10798: return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r'));
10799: }
10800:
10801: 10802: 10803: 10804: 10805: 10806: 10807:
10808: protected function _datastring($s, $n=0) {
10809: if ($n == 0) {
10810: $n = $this->n;
10811: }
10812: $s = $this->_encrypt_data($n, $s);
10813: return '('. $this->_escape($s).')';
10814: }
10815:
10816: 10817: 10818: 10819: 10820: 10821: 10822:
10823: protected function _datestring($n=0) {
10824: $current_time = substr_replace(date('YmdHisO'), '\'', (0 - 2), 0).'\'';
10825: return $this->_datastring('D:'.$current_time, $n);
10826: }
10827:
10828: 10829: 10830: 10831: 10832: 10833: 10834:
10835: protected function _textstring($s, $n=0) {
10836: if ($this->isunicode) {
10837:
10838: $s = $this->UTF8ToUTF16BE($s, true);
10839: }
10840: return $this->_datastring($s, $n);
10841: }
10842:
10843: 10844: 10845: 10846: 10847: 10848: 10849: 10850:
10851: protected function _escapetext($s) {
10852: if ($this->isunicode) {
10853: if (($this->CurrentFont['type'] == 'core') OR ($this->CurrentFont['type'] == 'TrueType') OR ($this->CurrentFont['type'] == 'Type1')) {
10854: $s = $this->UTF8ToLatin1($s);
10855: } else {
10856:
10857: $s = $this->utf8StrRev($s, false, $this->tmprtl);
10858: }
10859: }
10860: return $this->_escape($s);
10861: }
10862:
10863: 10864: 10865: 10866: 10867: 10868: 10869: 10870:
10871: protected function _getrawstream($s, $n=0) {
10872: if ($n <= 0) {
10873:
10874: $n = $this->n;
10875: }
10876: return $this->_encrypt_data($n, $s);
10877: }
10878:
10879: 10880: 10881: 10882: 10883: 10884: 10885:
10886: protected function _getstream($s, $n=0) {
10887: return 'stream'."\n".$this->_getrawstream($s, $n)."\n".'endstream';
10888: }
10889:
10890: 10891: 10892: 10893: 10894: 10895: 10896:
10897: protected function _putstream($s, $n=0) {
10898: $this->_out($this->_getstream($s, $n));
10899: }
10900:
10901: 10902: 10903: 10904: 10905:
10906: protected function _out($s) {
10907: if ($this->state == 2) {
10908: if ($this->inxobj) {
10909:
10910: $this->xobjects[$this->xobjid]['outdata'] .= $s."\n";
10911: } elseif ((!$this->InFooter) AND isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) {
10912:
10913: $pagebuff = $this->getPageBuffer($this->page);
10914: $page = substr($pagebuff, 0, -$this->footerlen[$this->page]);
10915: $footer = substr($pagebuff, -$this->footerlen[$this->page]);
10916: $this->setPageBuffer($this->page, $page.$s."\n".$footer);
10917:
10918: $this->footerpos[$this->page] += strlen($s."\n");
10919: } else {
10920: $this->setPageBuffer($this->page, $s."\n", true);
10921: }
10922: } else {
10923: $this->setBuffer($s."\n");
10924: }
10925: }
10926:
10927: 10928: 10929: 10930: 10931: 10932: 10933: 10934: 10935: 10936: 10937: 10938: 10939: 10940: 10941: 10942: 10943: 10944: 10945: 10946: 10947: 10948: 10949: 10950: 10951: 10952: 10953: 10954: 10955: 10956: 10957: 10958: 10959: 10960:
10961: protected function UTF8StringToArray($str) {
10962:
10963: $strkey = md5($str);
10964: if (isset($this->cache_UTF8StringToArray[$strkey])) {
10965:
10966: $chrarray = $this->cache_UTF8StringToArray[$strkey]['s'];
10967: if (!isset($this->cache_UTF8StringToArray[$strkey]['f'][$this->CurrentFont['fontkey']])) {
10968: if ($this->isunicode) {
10969: foreach ($chrarray as $chr) {
10970:
10971: $this->CurrentFont['subsetchars'][$chr] = true;
10972: }
10973:
10974: $this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']);
10975: }
10976: $this->cache_UTF8StringToArray[$strkey]['f'][$this->CurrentFont['fontkey']] = true;
10977: }
10978: return $chrarray;
10979: }
10980:
10981: if ($this->cache_size_UTF8StringToArray >= $this->cache_maxsize_UTF8StringToArray) {
10982:
10983: array_shift($this->cache_UTF8StringToArray);
10984: }
10985:
10986: $this->cache_UTF8StringToArray[$strkey] = array('s' => array(), 'f' => array());
10987: ++$this->cache_size_UTF8StringToArray;
10988: if (!$this->isunicode) {
10989:
10990: $strarr = array();
10991: $strlen = strlen($str);
10992: for ($i=0; $i < $strlen; ++$i) {
10993: $strarr[] = ord($str{$i});
10994: }
10995:
10996: $this->cache_UTF8StringToArray[$strkey]['s'] = $strarr;
10997: $this->cache_UTF8StringToArray[$strkey]['f'][$this->CurrentFont['fontkey']] = true;
10998: return $strarr;
10999: }
11000: $unichar = -1;
11001: $unicode = array();
11002: $bytes = array();
11003: $numbytes = 1;
11004: $str .= '';
11005: $length = strlen($str);
11006: for ($i = 0; $i < $length; ++$i) {
11007: $char = ord($str{$i});
11008: if (count($bytes) == 0) {
11009: if ($char <= 0x7F) {
11010: $unichar = $char;
11011: $numbytes = 1;
11012: } elseif (($char >> 0x05) == 0x06) {
11013: $bytes[] = ($char - 0xC0) << 0x06;
11014: $numbytes = 2;
11015: } elseif (($char >> 0x04) == 0x0E) {
11016: $bytes[] = ($char - 0xE0) << 0x0C;
11017: $numbytes = 3;
11018: } elseif (($char >> 0x03) == 0x1E) {
11019: $bytes[] = ($char - 0xF0) << 0x12;
11020: $numbytes = 4;
11021: } else {
11022:
11023: $unichar = 0xFFFD;
11024: $bytes = array();
11025: $numbytes = 1;
11026: }
11027: } elseif (($char >> 0x06) == 0x02) {
11028: $bytes[] = $char - 0x80;
11029: if (count($bytes) == $numbytes) {
11030:
11031: $char = $bytes[0];
11032: for ($j = 1; $j < $numbytes; ++$j) {
11033: $char += ($bytes[$j] << (($numbytes - $j - 1) * 0x06));
11034: }
11035: if ((($char >= 0xD800) AND ($char <= 0xDFFF)) OR ($char >= 0x10FFFF)) {
11036: 11037: 11038: 11039:
11040: $unichar = 0xFFFD;
11041: } else {
11042: $unichar = $char;
11043: }
11044:
11045: $bytes = array();
11046: $numbytes = 1;
11047: }
11048: } else {
11049:
11050: $unichar = 0xFFFD;
11051: $bytes = array();
11052: $numbytes = 1;
11053: }
11054: if ($unichar >= 0) {
11055:
11056: $unicode[] = $unichar;
11057:
11058: $this->CurrentFont['subsetchars'][$unichar] = true;
11059: $unichar = -1;
11060: }
11061: }
11062:
11063: $this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']);
11064:
11065: $this->cache_UTF8StringToArray[$strkey]['s'] = $unicode;
11066: $this->cache_UTF8StringToArray[$strkey]['f'][$this->CurrentFont['fontkey']] = true;
11067: return $unicode;
11068: }
11069:
11070: 11071: 11072: 11073: 11074: 11075: 11076: 11077: 11078: 11079:
11080: protected function UTF8ToUTF16BE($str, $setbom=true) {
11081: if (!$this->isunicode) {
11082: return $str;
11083: }
11084: $unicode = $this->UTF8StringToArray($str);
11085: return $this->arrUTF8ToUTF16BE($unicode, $setbom);
11086: }
11087:
11088: 11089: 11090: 11091: 11092: 11093: 11094: 11095:
11096: protected function UTF8ToLatin1($str) {
11097: if (!$this->isunicode) {
11098: return $str;
11099: }
11100: $outstr = '';
11101: $unicode = $this->UTF8StringToArray($str);
11102: foreach ($unicode as $char) {
11103: if ($char < 256) {
11104: $outstr .= chr($char);
11105: } elseif (array_key_exists($char, $this->unicode->uni_utf8tolatin)) {
11106:
11107: $outstr .= chr($this->unicode->uni_utf8tolatin[$char]);
11108: } elseif ($char == 0xFFFD) {
11109:
11110: } else {
11111: $outstr .= '?';
11112: }
11113: }
11114: return $outstr;
11115: }
11116:
11117: 11118: 11119: 11120: 11121: 11122: 11123: 11124:
11125: protected function UTF8ArrToLatin1($unicode) {
11126: if ((!$this->isunicode) OR $this->isUnicodeFont()) {
11127: return $unicode;
11128: }
11129: $outarr = array();
11130: foreach ($unicode as $char) {
11131: if ($char < 256) {
11132: $outarr[] = $char;
11133: } elseif (array_key_exists($char, $this->unicode->uni_utf8tolatin)) {
11134:
11135: $outarr[] = $this->unicode->uni_utf8tolatin[$char];
11136: } elseif ($char == 0xFFFD) {
11137:
11138: } else {
11139: $outarr[] = 63;
11140: }
11141: }
11142: return $outarr;
11143: }
11144:
11145: 11146: 11147: 11148: 11149: 11150: 11151: 11152: 11153: 11154: 11155: 11156: 11157: 11158: 11159: 11160: 11161: 11162: 11163: 11164: 11165: 11166: 11167: 11168: 11169: 11170: 11171: 11172: 11173: 11174: 11175: 11176: 11177: 11178: 11179: 11180: 11181: 11182:
11183: protected function arrUTF8ToUTF16BE($unicode, $setbom=true) {
11184: $outstr = '';
11185: if ($setbom) {
11186: $outstr .= "\xFE\xFF";
11187: }
11188: foreach ($unicode as $char) {
11189: if ($char == 0x200b) {
11190:
11191: } elseif ($char == 0xFFFD) {
11192: $outstr .= "\xFF\xFD";
11193: } elseif ($char < 0x10000) {
11194: $outstr .= chr($char >> 0x08);
11195: $outstr .= chr($char & 0xFF);
11196: } else {
11197: $char -= 0x10000;
11198: $w1 = 0xD800 | ($char >> 0x10);
11199: $w2 = 0xDC00 | ($char & 0x3FF);
11200: $outstr .= chr($w1 >> 0x08);
11201: $outstr .= chr($w1 & 0xFF);
11202: $outstr .= chr($w2 >> 0x08);
11203: $outstr .= chr($w2 & 0xFF);
11204: }
11205: }
11206: return $outstr;
11207: }
11208:
11209:
11210: 11211: 11212: 11213: 11214: 11215:
11216: public function ($font) {
11217: $this->header_font = $font;
11218: }
11219:
11220: 11221: 11222: 11223: 11224: 11225:
11226: public function () {
11227: return $this->header_font;
11228: }
11229:
11230: 11231: 11232: 11233: 11234: 11235:
11236: public function ($font) {
11237: $this->footer_font = $font;
11238: }
11239:
11240: 11241: 11242: 11243: 11244: 11245:
11246: public function () {
11247: return $this->footer_font;
11248: }
11249:
11250: 11251: 11252: 11253: 11254: 11255:
11256: public function setLanguageArray($language) {
11257: $this->l = $language;
11258: if (isset($this->l['a_meta_dir'])) {
11259: $this->rtl = $this->l['a_meta_dir']=='rtl' ? true : false;
11260: } else {
11261: $this->rtl = false;
11262: }
11263: }
11264:
11265: 11266: 11267: 11268:
11269: public function getPDFData() {
11270: if ($this->state < 3) {
11271: $this->Close();
11272: }
11273: return $this->buffer;
11274: }
11275:
11276: 11277: 11278: 11279: 11280: 11281: 11282: 11283: 11284: 11285: 11286: 11287:
11288: public function addHtmlLink($url, $name, $fill=false, $firstline=false, $color='', $style=-1, $firstblock=false) {
11289: if (!$this->empty_string($url) AND ($url{0} == '#')) {
11290:
11291: $lnkdata = explode(',', $url);
11292: if (isset($lnkdata[0])) {
11293: $page = intval(substr($lnkdata[0], 1));
11294: if (empty($page) OR ($page <= 0)) {
11295: $page = $this->page;
11296: }
11297: if (isset($lnkdata[1]) AND (strlen($lnkdata[1]) > 0)) {
11298: $lnky = floatval($lnkdata[1]);
11299: } else {
11300: $lnky = 0;
11301: }
11302: $url = $this->AddLink();
11303: $this->SetLink($url, $lnky, $page);
11304: }
11305: }
11306:
11307: $prevcolor = $this->fgcolor;
11308: $prevstyle = $this->FontStyle;
11309: if (empty($color)) {
11310: $this->SetTextColorArray($this->htmlLinkColorArray);
11311: } else {
11312: $this->SetTextColorArray($color);
11313: }
11314: if ($style == -1) {
11315: $this->SetFont('', $this->FontStyle.$this->htmlLinkFontStyle);
11316: } else {
11317: $this->SetFont('', $this->FontStyle.$style);
11318: }
11319: $ret = $this->Write($this->lasth, $name, $url, $fill, '', false, 0, $firstline, $firstblock, 0);
11320:
11321: $this->SetFont('', $prevstyle);
11322: $this->SetTextColorArray($prevcolor);
11323: return $ret;
11324: }
11325:
11326: 11327: 11328: 11329: 11330: 11331:
11332: public function convertHTMLColorToDec($color='#FFFFFF') {
11333: $returncolor = false;
11334: $color = preg_replace('/[\s]*/', '', $color);
11335: $color = strtolower($color);
11336: if (($dotpos = strpos($color, '.')) !== false) {
11337:
11338: $color = substr($color, ($dotpos + 1));
11339: }
11340: if (strlen($color) == 0) {
11341: return false;
11342: }
11343:
11344: if (substr($color, 0, 3) == 'rgb') {
11345: $codes = substr($color, 4);
11346: $codes = str_replace(')', '', $codes);
11347: $returncolor = explode(',', $codes);
11348: return $returncolor;
11349: }
11350:
11351: if (substr($color, 0, 4) == 'cmyk') {
11352: $codes = substr($color, 5);
11353: $codes = str_replace(')', '', $codes);
11354: $returncolor = explode(',', $codes);
11355: return $returncolor;
11356: }
11357:
11358: if (substr($color, 0, 1) != '#') {
11359:
11360: if (isset($this->webcolor[$color])) {
11361: $color_code = $this->webcolor[$color];
11362: } else {
11363: return false;
11364: }
11365: } else {
11366: $color_code = substr($color, 1);
11367: }
11368:
11369: switch (strlen($color_code)) {
11370: case 3: {
11371:
11372: $r = substr($color_code, 0, 1);
11373: $g = substr($color_code, 1, 1);
11374: $b = substr($color_code, 2, 1);
11375: $returncolor['R'] = hexdec($r.$r);
11376: $returncolor['G'] = hexdec($g.$g);
11377: $returncolor['B'] = hexdec($b.$b);
11378: break;
11379: }
11380: case 6: {
11381:
11382: $returncolor['R'] = hexdec(substr($color_code, 0, 2));
11383: $returncolor['G'] = hexdec(substr($color_code, 2, 2));
11384: $returncolor['B'] = hexdec(substr($color_code, 4, 2));
11385: break;
11386: }
11387: }
11388: return $returncolor;
11389: }
11390:
11391: 11392: 11393: 11394: 11395: 11396: 11397:
11398: public function pixelsToUnits($px) {
11399: return ($px / ($this->imgscale * $this->k));
11400: }
11401:
11402: 11403: 11404: 11405: 11406: 11407: 11408:
11409: public function unhtmlentities($text_to_convert) {
11410: return html_entity_decode($text_to_convert, ENT_QUOTES, $this->encoding);
11411: }
11412:
11413:
11414:
11415: 11416: 11417: 11418: 11419: 11420: 11421: 11422:
11423: protected function getRandomSeed($seed='') {
11424: $seed .= microtime();
11425: if (function_exists('openssl_random_pseudo_bytes')) {
11426: $seed .= openssl_random_pseudo_bytes(512);
11427: }
11428: $seed .= uniqid('', true);
11429: $seed .= rand();
11430: $seed .= getmypid();
11431: $seed .= __FILE__;
11432: $seed .= $this->bufferlen;
11433: if (isset($_SERVER['REMOTE_ADDR'])) {
11434: $seed .= $_SERVER['REMOTE_ADDR'];
11435: }
11436: if (isset($_SERVER['HTTP_USER_AGENT'])) {
11437: $seed .= $_SERVER['HTTP_USER_AGENT'];
11438: }
11439: if (isset($_SERVER['HTTP_ACCEPT'])) {
11440: $seed .= $_SERVER['HTTP_ACCEPT'];
11441: }
11442: if (isset($_SERVER['HTTP_ACCEPT_ENCODING'])) {
11443: $seed .= $_SERVER['HTTP_ACCEPT_ENCODING'];
11444: }
11445: if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
11446: $seed .= $_SERVER['HTTP_ACCEPT_LANGUAGE'];
11447: }
11448: if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) {
11449: $seed .= $_SERVER['HTTP_ACCEPT_CHARSET'];
11450: }
11451: $seed .= rand();
11452: $seed .= uniqid('', true);
11453: $seed .= microtime();
11454: return $seed;
11455: }
11456:
11457: 11458: 11459: 11460: 11461: 11462: 11463: 11464: 11465:
11466: protected function _objectkey($n) {
11467: $objkey = $this->encryptdata['key'].pack('VXxx', $n);
11468: if ($this->encryptdata['mode'] == 2) {
11469:
11470: $objkey .= "\x73\x41\x6C\x54";
11471: }
11472: $objkey = substr($this->_md5_16($objkey), 0, (($this->encryptdata['Length'] / 8) + 5));
11473: $objkey = substr($objkey, 0, 16);
11474: return $objkey;
11475: }
11476:
11477: 11478: 11479: 11480: 11481: 11482: 11483: 11484: 11485:
11486: protected function _encrypt_data($n, $s) {
11487: if (!$this->encrypted) {
11488: return $s;
11489: }
11490: switch ($this->encryptdata['mode']) {
11491: case 0:
11492: case 1: {
11493: $s = $this->_RC4($this->_objectkey($n), $s);
11494: break;
11495: }
11496: case 2: {
11497: $s = $this->_AES($this->_objectkey($n), $s);
11498: break;
11499: }
11500: case 3: {
11501: $s = $this->_AES($this->encryptdata['key'], $s);
11502: break;
11503: }
11504: }
11505: return $s;
11506: }
11507:
11508: 11509: 11510: 11511: 11512: 11513:
11514: protected function _putencryption() {
11515: if (!$this->encrypted) {
11516: return;
11517: }
11518: $this->encryptdata['objid'] = $this->_newobj();
11519: $out = '<<';
11520: if (!isset($this->encryptdata['Filter']) OR empty($this->encryptdata['Filter'])) {
11521: $this->encryptdata['Filter'] = 'Standard';
11522: }
11523: $out .= ' /Filter /'.$this->encryptdata['Filter'];
11524: if (isset($this->encryptdata['SubFilter']) AND !empty($this->encryptdata['SubFilter'])) {
11525: $out .= ' /SubFilter /'.$this->encryptdata['SubFilter'];
11526: }
11527: if (!isset($this->encryptdata['V']) OR empty($this->encryptdata['V'])) {
11528: $this->encryptdata['V'] = 1;
11529: }
11530:
11531: $out .= ' /V '.$this->encryptdata['V'];
11532: if (isset($this->encryptdata['Length']) AND !empty($this->encryptdata['Length'])) {
11533:
11534: $out .= ' /Length '.$this->encryptdata['Length'];
11535: } else {
11536: $out .= ' /Length 40';
11537: }
11538: if ($this->encryptdata['V'] >= 4) {
11539: if (!isset($this->encryptdata['StmF']) OR empty($this->encryptdata['StmF'])) {
11540: $this->encryptdata['StmF'] = 'Identity';
11541: }
11542: if (!isset($this->encryptdata['StrF']) OR empty($this->encryptdata['StrF'])) {
11543:
11544: $this->encryptdata['StrF'] = 'Identity';
11545: }
11546:
11547: if (isset($this->encryptdata['CF']) AND !empty($this->encryptdata['CF'])) {
11548: $out .= ' /CF <<';
11549: $out .= ' /'.$this->encryptdata['StmF'].' <<';
11550: $out .= ' /Type /CryptFilter';
11551: if (isset($this->encryptdata['CF']['CFM']) AND !empty($this->encryptdata['CF']['CFM'])) {
11552:
11553: $out .= ' /CFM /'.$this->encryptdata['CF']['CFM'];
11554: if ($this->encryptdata['pubkey']) {
11555: $out .= ' /Recipients [';
11556: foreach ($this->encryptdata['Recipients'] as $rec) {
11557: $out .= ' <'.$rec.'>';
11558: }
11559: $out .= ' ]';
11560: if (isset($this->encryptdata['CF']['EncryptMetadata']) AND (!$this->encryptdata['CF']['EncryptMetadata'])) {
11561: $out .= ' /EncryptMetadata false';
11562: } else {
11563: $out .= ' /EncryptMetadata true';
11564: }
11565: }
11566: } else {
11567: $out .= ' /CFM /None';
11568: }
11569: if (isset($this->encryptdata['CF']['AuthEvent']) AND !empty($this->encryptdata['CF']['AuthEvent'])) {
11570:
11571: $out .= ' /AuthEvent /'.$this->encryptdata['CF']['AuthEvent'];
11572: } else {
11573: $out .= ' /AuthEvent /DocOpen';
11574: }
11575: if (isset($this->encryptdata['CF']['Length']) AND !empty($this->encryptdata['CF']['Length'])) {
11576:
11577: $out .= ' /Length '.$this->encryptdata['CF']['Length'];
11578: }
11579: $out .= ' >> >>';
11580: }
11581:
11582: $out .= ' /StmF /'.$this->encryptdata['StmF'];
11583:
11584: $out .= ' /StrF /'.$this->encryptdata['StrF'];
11585: if (isset($this->encryptdata['EFF']) AND !empty($this->encryptdata['EFF'])) {
11586:
11587: $out .= ' /EFF /'.$this->encryptdata[''];
11588: }
11589: }
11590:
11591: if ($this->encryptdata['pubkey']) {
11592: if (($this->encryptdata['V'] < 4) AND isset($this->encryptdata['Recipients']) AND !empty($this->encryptdata['Recipients'])) {
11593: $out .= ' /Recipients [';
11594: foreach ($this->encryptdata['Recipients'] as $rec) {
11595: $out .= ' <'.$rec.'>';
11596: }
11597: $out .= ' ]';
11598: }
11599: } else {
11600: $out .= ' /R';
11601: if ($this->encryptdata['V'] == 5) {
11602: $out .= ' 5';
11603: $out .= ' /OE ('.$this->_escape($this->encryptdata['OE']).')';
11604: $out .= ' /UE ('.$this->_escape($this->encryptdata['UE']).')';
11605: $out .= ' /Perms ('.$this->_escape($this->encryptdata['perms']).')';
11606: } elseif ($this->encryptdata['V'] == 4) {
11607: $out .= ' 4';
11608: } elseif ($this->encryptdata['V'] < 2) {
11609: $out .= ' 2';
11610: } else {
11611: $out .= ' 3';
11612: }
11613: $out .= ' /O ('.$this->_escape($this->encryptdata['O']).')';
11614: $out .= ' /U ('.$this->_escape($this->encryptdata['U']).')';
11615: $out .= ' /P '.$this->encryptdata['P'];
11616: if (isset($this->encryptdata['EncryptMetadata']) AND (!$this->encryptdata['EncryptMetadata'])) {
11617: $out .= ' /EncryptMetadata false';
11618: } else {
11619: $out .= ' /EncryptMetadata true';
11620: }
11621: }
11622: $out .= ' >>';
11623: $out .= "\n".'endobj';
11624: $this->_out($out);
11625: }
11626:
11627: 11628: 11629: 11630: 11631: 11632: 11633: 11634: 11635: 11636:
11637: protected function _RC4($key, $text) {
11638: if (function_exists('mcrypt_decrypt') AND ($out = @mcrypt_decrypt(MCRYPT_ARCFOUR, $key, $text, MCRYPT_MODE_STREAM, ''))) {
11639:
11640: return $out;
11641: }
11642: if ($this->last_enc_key != $key) {
11643: $k = str_repeat($key, ((256 / strlen($key)) + 1));
11644: $rc4 = range(0, 255);
11645: $j = 0;
11646: for ($i = 0; $i < 256; ++$i) {
11647: $t = $rc4[$i];
11648: $j = ($j + $t + ord($k{$i})) % 256;
11649: $rc4[$i] = $rc4[$j];
11650: $rc4[$j] = $t;
11651: }
11652: $this->last_enc_key = $key;
11653: $this->last_enc_key_c = $rc4;
11654: } else {
11655: $rc4 = $this->last_enc_key_c;
11656: }
11657: $len = strlen($text);
11658: $a = 0;
11659: $b = 0;
11660: $out = '';
11661: for ($i = 0; $i < $len; ++$i) {
11662: $a = ($a + 1) % 256;
11663: $t = $rc4[$a];
11664: $b = ($b + $t) % 256;
11665: $rc4[$a] = $rc4[$b];
11666: $rc4[$b] = $t;
11667: $k = $rc4[($rc4[$a] + $rc4[$b]) % 256];
11668: $out .= chr(ord($text{$i}) ^ $k);
11669: }
11670: return $out;
11671: }
11672:
11673: 11674: 11675: 11676: 11677: 11678: 11679: 11680: 11681: 11682:
11683: protected function _AES($key, $text) {
11684:
11685: $padding = 16 - (strlen($text) % 16);
11686: $text .= str_repeat(chr($padding), $padding);
11687: $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
11688: $text = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv);
11689: $text = $iv.$text;
11690: return $text;
11691: }
11692:
11693: 11694: 11695: 11696: 11697: 11698: 11699: 11700:
11701: protected function _md5_16($str) {
11702: return pack('H*', md5($str));
11703: }
11704:
11705: 11706: 11707: 11708: 11709: 11710: 11711:
11712: protected function _Uvalue() {
11713: if ($this->encryptdata['mode'] == 0) {
11714: return $this->_RC4($this->encryptdata['key'], $this->enc_padding);
11715: } elseif ($this->encryptdata['mode'] < 3) {
11716: $tmp = $this->_md5_16($this->enc_padding.$this->encryptdata['fileid']);
11717: $enc = $this->_RC4($this->encryptdata['key'], $tmp);
11718: $len = strlen($tmp);
11719: for ($i = 1; $i <= 19; ++$i) {
11720: $ek = '';
11721: for ($j = 0; $j < $len; ++$j) {
11722: $ek .= chr(ord($this->encryptdata['key']{$j}) ^ $i);
11723: }
11724: $enc = $this->_RC4($ek, $enc);
11725: }
11726: $enc .= str_repeat("\x00", 16);
11727: return substr($enc, 0, 32);
11728: } elseif ($this->encryptdata['mode'] == 3) {
11729: $seed = $this->_md5_16($this->getRandomSeed());
11730:
11731: $this->encryptdata['UVS'] = substr($seed, 0, 8);
11732:
11733: $this->encryptdata['UKS'] = substr($seed, 8, 16);
11734: return hash('sha256', $this->encryptdata['user_password'].$this->encryptdata['UVS'], true).$this->encryptdata['UVS'].$this->encryptdata['UKS'];
11735: }
11736: }
11737:
11738: 11739: 11740: 11741: 11742: 11743: 11744:
11745: protected function _UEvalue() {
11746: $hashkey = hash('sha256', $this->encryptdata['user_password'].$this->encryptdata['UKS'], true);
11747: $iv = str_repeat("\x00", mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
11748: return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $hashkey, $this->encryptdata['key'], MCRYPT_MODE_CBC, $iv);
11749: }
11750:
11751: 11752: 11753: 11754: 11755: 11756: 11757:
11758: protected function _Ovalue() {
11759: if ($this->encryptdata['mode'] < 3) {
11760: $tmp = $this->_md5_16($this->encryptdata['owner_password']);
11761: if ($this->encryptdata['mode'] > 0) {
11762: for ($i = 0; $i < 50; ++$i) {
11763: $tmp = $this->_md5_16($tmp);
11764: }
11765: }
11766: $owner_key = substr($tmp, 0, ($this->encryptdata['Length'] / 8));
11767: $enc = $this->_RC4($owner_key, $this->encryptdata['user_password']);
11768: if ($this->encryptdata['mode'] > 0) {
11769: $len = strlen($owner_key);
11770: for ($i = 1; $i <= 19; ++$i) {
11771: $ek = '';
11772: for ($j = 0; $j < $len; ++$j) {
11773: $ek .= chr(ord($owner_key{$j}) ^ $i);
11774: }
11775: $enc = $this->_RC4($ek, $enc);
11776: }
11777: }
11778: return $enc;
11779: } elseif ($this->encryptdata['mode'] == 3) {
11780: $seed = $this->_md5_16($this->getRandomSeed());
11781:
11782: $this->encryptdata['OVS'] = substr($seed, 0, 8);
11783:
11784: $this->encryptdata['OKS'] = substr($seed, 8, 16);
11785: return hash('sha256', $this->encryptdata['owner_password'].$this->encryptdata['OVS'].$this->encryptdata['U'], true).$this->encryptdata['OVS'].$this->encryptdata['OKS'];
11786: }
11787: }
11788:
11789: 11790: 11791: 11792: 11793: 11794: 11795:
11796: protected function _OEvalue() {
11797: $hashkey = hash('sha256', $this->encryptdata['owner_password'].$this->encryptdata['OKS'].$this->encryptdata['U'], true);
11798: $iv = str_repeat("\x00", mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
11799: return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $hashkey, $this->encryptdata['key'], MCRYPT_MODE_CBC, $iv);
11800: }
11801:
11802: 11803: 11804: 11805: 11806: 11807: 11808:
11809: protected function _fixAES256Password($password) {
11810: $psw = '';
11811: $psw_array = $this->utf8Bidi($this->UTF8StringToArray($password), $password, $this->rtl);
11812: foreach ($psw_array as $c) {
11813: $psw .= $this->unichr($c);
11814: }
11815: return substr($psw, 0, 127);
11816: }
11817:
11818: 11819: 11820: 11821: 11822: 11823:
11824: protected function _generateencryptionkey() {
11825: $keybytelen = ($this->encryptdata['Length'] / 8);
11826: if (!$this->encryptdata['pubkey']) {
11827: if ($this->encryptdata['mode'] == 3) {
11828:
11829: $this->encryptdata['key'] = substr(hash('sha256', $this->getRandomSeed(), true), 0, $keybytelen);
11830:
11831: $this->encryptdata['user_password'] = $this->_fixAES256Password($this->encryptdata['user_password']);
11832: $this->encryptdata['owner_password'] = $this->_fixAES256Password($this->encryptdata['owner_password']);
11833:
11834: $this->encryptdata['U'] = $this->_Uvalue();
11835:
11836: $this->encryptdata['UE'] = $this->_UEvalue();
11837:
11838: $this->encryptdata['O'] = $this->_Ovalue();
11839:
11840: $this->encryptdata['OE'] = $this->_OEvalue();
11841:
11842: $this->encryptdata['P'] = $this->encryptdata['protection'];
11843:
11844: $perms = $this->getEncPermissionsString($this->encryptdata['protection']);
11845: $perms .= chr(255).chr(255).chr(255).chr(255);
11846: if (isset($this->encryptdata['CF']['EncryptMetadata']) AND (!$this->encryptdata['CF']['EncryptMetadata'])) {
11847: $perms .= 'F';
11848: } else {
11849: $perms .= 'T';
11850: }
11851: $perms .= 'adb';
11852: $perms .= 'nick';
11853: $iv = str_repeat("\x00", mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB));
11854: $this->encryptdata['perms'] = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->encryptdata['key'], $perms, MCRYPT_MODE_ECB, $iv);
11855: } else {
11856:
11857: $this->encryptdata['user_password'] = substr($this->encryptdata['user_password'].$this->enc_padding, 0, 32);
11858: $this->encryptdata['owner_password'] = substr($this->encryptdata['owner_password'].$this->enc_padding, 0, 32);
11859:
11860: $this->encryptdata['O'] = $this->_Ovalue();
11861:
11862: $permissions = $this->getEncPermissionsString($this->encryptdata['protection']);
11863:
11864: $tmp = $this->_md5_16($this->encryptdata['user_password'].$this->encryptdata['O'].$permissions.$this->encryptdata['fileid']);
11865: if ($this->encryptdata['mode'] > 0) {
11866: for ($i = 0; $i < 50; ++$i) {
11867: $tmp = $this->_md5_16(substr($tmp, 0, $keybytelen));
11868: }
11869: }
11870: $this->encryptdata['key'] = substr($tmp, 0, $keybytelen);
11871:
11872: $this->encryptdata['U'] = $this->_Uvalue();
11873:
11874: $this->encryptdata['P'] = $this->encryptdata['protection'];
11875: }
11876: } else {
11877:
11878: $seed = sha1($this->getRandomSeed(), true);
11879: $recipient_bytes = '';
11880: foreach ($this->encryptdata['pubkeys'] as $pubkey) {
11881:
11882: if (isset($pubkey['p'])) {
11883: $pkprotection = $this->getUserPermissionCode($pubkey['p'], $this->encryptdata['mode']);
11884: } else {
11885: $pkprotection = $this->encryptdata['protection'];
11886: }
11887:
11888: $pkpermissions = $this->getEncPermissionsString($pkprotection);
11889:
11890: $envelope = $seed.$pkpermissions;
11891:
11892: $tempkeyfile = tempnam(K_PATH_CACHE, 'tmpkey_');
11893: $f = fopen($tempkeyfile, 'wb');
11894: if (!$f) {
11895: $this->Error('Unable to create temporary key file: '.$tempkeyfile);
11896: }
11897: $envelope_lenght = strlen($envelope);
11898: fwrite($f, $envelope, $envelope_lenght);
11899: fclose($f);
11900: $tempencfile = tempnam(K_PATH_CACHE, 'tmpenc_');
11901: if (!openssl_pkcs7_encrypt($tempkeyfile, $tempencfile, $pubkey['c'], array(), PKCS7_DETACHED | PKCS7_BINARY)) {
11902: $this->Error('Unable to encrypt the file: '.$tempkeyfile);
11903: }
11904: unlink($tempkeyfile);
11905:
11906: $signature = file_get_contents($tempencfile, false, null, $envelope_lenght);
11907: unlink($tempencfile);
11908:
11909: $signature = substr($signature, strpos($signature, 'Content-Disposition'));
11910: $tmparr = explode("\n\n", $signature);
11911: $signature = trim($tmparr[1]);
11912: unset($tmparr);
11913:
11914: $signature = base64_decode($signature);
11915:
11916: $hexsignature = current(unpack('H*', $signature));
11917:
11918: $this->encryptdata['Recipients'][] = $hexsignature;
11919:
11920: $recipient_bytes .= $signature;
11921: }
11922:
11923: if ($this->encryptdata['mode'] == 3) {
11924: $this->encryptdata['key'] = substr(hash('sha256', $seed.$recipient_bytes, true), 0, $keybytelen);
11925: } else {
11926: $this->encryptdata['key'] = substr(sha1($seed.$recipient_bytes, true), 0, $keybytelen);
11927: }
11928: }
11929: }
11930:
11931: 11932: 11933: 11934: 11935: 11936: 11937: 11938:
11939: protected function getUserPermissionCode($permissions, $mode=0) {
11940: $options = array(
11941: 'owner' => 2,
11942: 'print' => 4,
11943: 'modify' => 8,
11944: 'copy' => 16,
11945: 'annot-forms' => 32,
11946: 'fill-forms' => 256,
11947: 'extract' => 512,
11948: 'assemble' => 1024,
11949: 'print-high' => 2048
11950: );
11951: $protection = 2147422012;
11952: foreach ($permissions as $permission) {
11953: if (!isset($options[$permission])) {
11954: $this->Error('Incorrect permission: '.$permission);
11955: }
11956: if (($mode > 0) OR ($options[$permission] <= 32)) {
11957:
11958: if ($options[$permission] == 2) {
11959:
11960: $protection += $options[$permission];
11961: } else {
11962: $protection -= $options[$permission];
11963: }
11964: }
11965: }
11966: return $protection;
11967: }
11968:
11969: 11970: 11971: 11972: 11973: 11974: 11975: 11976: 11977: 11978: 11979: 11980: 11981: 11982:
11983: public function SetProtection($permissions=array('print', 'modify', 'copy', 'annot-forms', 'fill-forms', 'extract', 'assemble', 'print-high'), $user_pass='', $owner_pass=null, $mode=0, $pubkeys=null) {
11984: $this->encryptdata['protection'] = $this->getUserPermissionCode($permissions, $mode);
11985: if (($pubkeys !== null) AND (is_array($pubkeys))) {
11986:
11987: $this->encryptdata['pubkeys'] = $pubkeys;
11988: if ($mode == 0) {
11989:
11990: $mode = 1;
11991: }
11992: if (!function_exists('openssl_pkcs7_encrypt')) {
11993: $this->Error('Public-Key Security requires openssl library.');
11994: }
11995:
11996: $this->encryptdata['pubkey'] = true;
11997: $this->encryptdata['Filter'] = 'Adobe.PubSec';
11998: $this->encryptdata['StmF'] = 'DefaultCryptFilter';
11999: $this->encryptdata['StrF'] = 'DefaultCryptFilter';
12000: } else {
12001:
12002: $this->encryptdata['pubkey'] = false;
12003: $this->encryptdata['Filter'] = 'Standard';
12004: $this->encryptdata['StmF'] = 'StdCF';
12005: $this->encryptdata['StrF'] = 'StdCF';
12006: }
12007: if ($mode > 1) {
12008: if (!extension_loaded('mcrypt')) {
12009: $this->Error('AES encryption requires mcrypt library (http://www.php.net/manual/en/mcrypt.requirements.php).');
12010: }
12011: if (mcrypt_get_cipher_name(MCRYPT_RIJNDAEL_128) === false) {
12012: $this->Error('AES encryption requires MCRYPT_RIJNDAEL_128 cypher.');
12013: }
12014: if (($mode == 3) AND !function_exists('hash')) {
12015:
12016: $this->Error('AES 256 encryption requires HASH Message Digest Framework (http://www.php.net/manual/en/book.hash.php).');
12017: }
12018: }
12019: if ($owner_pass === null) {
12020: $owner_pass = md5($this->getRandomSeed());
12021: }
12022: $this->encryptdata['user_password'] = $user_pass;
12023: $this->encryptdata['owner_password'] = $owner_pass;
12024: $this->encryptdata['mode'] = $mode;
12025: switch ($mode) {
12026: case 0: {
12027: $this->encryptdata['V'] = 1;
12028: $this->encryptdata['Length'] = 40;
12029: $this->encryptdata['CF']['CFM'] = 'V2';
12030: break;
12031: }
12032: case 1: {
12033: $this->encryptdata['V'] = 2;
12034: $this->encryptdata['Length'] = 128;
12035: $this->encryptdata['CF']['CFM'] = 'V2';
12036: if ($this->encryptdata['pubkey']) {
12037: $this->encryptdata['SubFilter'] = 'adbe.pkcs7.s4';
12038: $this->encryptdata['Recipients'] = array();
12039: }
12040: break;
12041: }
12042: case 2: {
12043: $this->encryptdata['V'] = 4;
12044: $this->encryptdata['Length'] = 128;
12045: $this->encryptdata['CF']['CFM'] = 'AESV2';
12046: $this->encryptdata['CF']['Length'] = 128;
12047: if ($this->encryptdata['pubkey']) {
12048: $this->encryptdata['SubFilter'] = 'adbe.pkcs7.s5';
12049: $this->encryptdata['Recipients'] = array();
12050: }
12051: break;
12052: }
12053: case 3: {
12054: $this->encryptdata['V'] = 5;
12055: $this->encryptdata['Length'] = 256;
12056: $this->encryptdata['CF']['CFM'] = 'AESV3';
12057: $this->encryptdata['CF']['Length'] = 256;
12058: if ($this->encryptdata['pubkey']) {
12059: $this->encryptdata['SubFilter'] = 'adbe.pkcs7.s5';
12060: $this->encryptdata['Recipients'] = array();
12061: }
12062: break;
12063: }
12064: }
12065: $this->encrypted = true;
12066: $this->encryptdata['fileid'] = $this->convertHexStringToString($this->file_id);
12067: $this->_generateencryptionkey();
12068: }
12069:
12070: 12071: 12072: 12073: 12074: 12075: 12076: 12077:
12078: protected function convertHexStringToString($bs) {
12079: $string = '';
12080: $bslenght = strlen($bs);
12081: if (($bslenght % 2) != 0) {
12082:
12083: $bs .= '0';
12084: ++$bslenght;
12085: }
12086: for ($i = 0; $i < $bslenght; $i += 2) {
12087: $string .= chr(hexdec($bs{$i}.$bs{($i + 1)}));
12088: }
12089: return $string;
12090: }
12091:
12092: 12093: 12094: 12095: 12096: 12097: 12098: 12099:
12100: protected function convertStringToHexString($s) {
12101: $bs = '';
12102: $chars = preg_split('//', $s, -1, PREG_SPLIT_NO_EMPTY);
12103: foreach ($chars as $c) {
12104: $bs .= sprintf('%02s', dechex(ord($c)));
12105: }
12106: return $bs;
12107: }
12108:
12109: 12110: 12111: 12112: 12113: 12114: 12115: 12116:
12117: protected function getEncPermissionsString($protection) {
12118: $binprot = sprintf('%032b', $protection);
12119: $str = chr(bindec(substr($binprot, 24, 8)));
12120: $str .= chr(bindec(substr($binprot, 16, 8)));
12121: $str .= chr(bindec(substr($binprot, 8, 8)));
12122: $str .= chr(bindec(substr($binprot, 0, 8)));
12123: return $str;
12124: }
12125:
12126:
12127:
12128:
12129:
12130: 12131: 12132: 12133: 12134: 12135: 12136: 12137:
12138: public function StartTransform() {
12139: $this->_out('q');
12140: if ($this->inxobj) {
12141:
12142: $this->xobjects[$this->xobjid]['transfmrk'][] = strlen($this->xobjects[$this->xobjid]['outdata']);
12143: } else {
12144: $this->transfmrk[$this->page][] = $this->pagelen[$this->page];
12145: }
12146: ++$this->transfmatrix_key;
12147: $this->transfmatrix[$this->transfmatrix_key] = array();
12148: }
12149:
12150: 12151: 12152: 12153: 12154: 12155: 12156: 12157:
12158: public function StopTransform() {
12159: $this->_out('Q');
12160: if (isset($this->transfmatrix[$this->transfmatrix_key])) {
12161: array_pop($this->transfmatrix[$this->transfmatrix_key]);
12162: --$this->transfmatrix_key;
12163: }
12164: if ($this->inxobj) {
12165:
12166: array_pop($this->xobjects[$this->xobjid]['transfmrk']);
12167: } else {
12168: array_pop($this->transfmrk[$this->page]);
12169: }
12170: }
12171: 12172: 12173: 12174: 12175: 12176: 12177: 12178: 12179:
12180: public function ScaleX($s_x, $x='', $y='') {
12181: $this->Scale($s_x, 100, $x, $y);
12182: }
12183:
12184: 12185: 12186: 12187: 12188: 12189: 12190: 12191: 12192:
12193: public function ScaleY($s_y, $x='', $y='') {
12194: $this->Scale(100, $s_y, $x, $y);
12195: }
12196:
12197: 12198: 12199: 12200: 12201: 12202: 12203: 12204: 12205:
12206: public function ScaleXY($s, $x='', $y='') {
12207: $this->Scale($s, $s, $x, $y);
12208: }
12209:
12210: 12211: 12212: 12213: 12214: 12215: 12216: 12217: 12218: 12219:
12220: public function Scale($s_x, $s_y, $x='', $y='') {
12221: if ($x === '') {
12222: $x = $this->x;
12223: }
12224: if ($y === '') {
12225: $y = $this->y;
12226: }
12227: if (($s_x == 0) OR ($s_y == 0)) {
12228: $this->Error('Please do not use values equal to zero for scaling');
12229: }
12230: $y = ($this->h - $y) * $this->k;
12231: $x *= $this->k;
12232:
12233: $s_x /= 100;
12234: $s_y /= 100;
12235: $tm = array();
12236: $tm[0] = $s_x;
12237: $tm[1] = 0;
12238: $tm[2] = 0;
12239: $tm[3] = $s_y;
12240: $tm[4] = $x * (1 - $s_x);
12241: $tm[5] = $y * (1 - $s_y);
12242:
12243: $this->Transform($tm);
12244: }
12245:
12246: 12247: 12248: 12249: 12250: 12251: 12252:
12253: public function MirrorH($x='') {
12254: $this->Scale(-100, 100, $x);
12255: }
12256:
12257: 12258: 12259: 12260: 12261: 12262: 12263:
12264: public function MirrorV($y='') {
12265: $this->Scale(100, -100, '', $y);
12266: }
12267:
12268: 12269: 12270: 12271: 12272: 12273: 12274: 12275:
12276: public function MirrorP($x='',$y='') {
12277: $this->Scale(-100, -100, $x, $y);
12278: }
12279:
12280: 12281: 12282: 12283: 12284: 12285: 12286: 12287: 12288:
12289: public function MirrorL($angle=0, $x='',$y='') {
12290: $this->Scale(-100, 100, $x, $y);
12291: $this->Rotate(-2*($angle-90), $x, $y);
12292: }
12293:
12294: 12295: 12296: 12297: 12298: 12299: 12300:
12301: public function TranslateX($t_x) {
12302: $this->Translate($t_x, 0);
12303: }
12304:
12305: 12306: 12307: 12308: 12309: 12310: 12311:
12312: public function TranslateY($t_y) {
12313: $this->Translate(0, $t_y);
12314: }
12315:
12316: 12317: 12318: 12319: 12320: 12321: 12322: 12323:
12324: public function Translate($t_x, $t_y) {
12325:
12326: $tm = array();
12327: $tm[0] = 1;
12328: $tm[1] = 0;
12329: $tm[2] = 0;
12330: $tm[3] = 1;
12331: $tm[4] = $t_x * $this->k;
12332: $tm[5] = -$t_y * $this->k;
12333:
12334: $this->Transform($tm);
12335: }
12336:
12337: 12338: 12339: 12340: 12341: 12342: 12343: 12344: 12345:
12346: public function Rotate($angle, $x='', $y='') {
12347: if ($x === '') {
12348: $x = $this->x;
12349: }
12350: if ($y === '') {
12351: $y = $this->y;
12352: }
12353: $y = ($this->h - $y) * $this->k;
12354: $x *= $this->k;
12355:
12356: $tm = array();
12357: $tm[0] = cos(deg2rad($angle));
12358: $tm[1] = sin(deg2rad($angle));
12359: $tm[2] = -$tm[1];
12360: $tm[3] = $tm[0];
12361: $tm[4] = $x + ($tm[1] * $y) - ($tm[0] * $x);
12362: $tm[5] = $y - ($tm[0] * $y) - ($tm[1] * $x);
12363:
12364: $this->Transform($tm);
12365: }
12366:
12367: 12368: 12369: 12370: 12371: 12372: 12373: 12374: 12375:
12376: public function SkewX($angle_x, $x='', $y='') {
12377: $this->Skew($angle_x, 0, $x, $y);
12378: }
12379:
12380: 12381: 12382: 12383: 12384: 12385: 12386: 12387: 12388:
12389: public function SkewY($angle_y, $x='', $y='') {
12390: $this->Skew(0, $angle_y, $x, $y);
12391: }
12392:
12393: 12394: 12395: 12396: 12397: 12398: 12399: 12400: 12401: 12402:
12403: public function Skew($angle_x, $angle_y, $x='', $y='') {
12404: if ($x === '') {
12405: $x = $this->x;
12406: }
12407: if ($y === '') {
12408: $y = $this->y;
12409: }
12410: if (($angle_x <= -90) OR ($angle_x >= 90) OR ($angle_y <= -90) OR ($angle_y >= 90)) {
12411: $this->Error('Please use values between -90 and +90 degrees for Skewing.');
12412: }
12413: $x *= $this->k;
12414: $y = ($this->h - $y) * $this->k;
12415:
12416: $tm = array();
12417: $tm[0] = 1;
12418: $tm[1] = tan(deg2rad($angle_y));
12419: $tm[2] = tan(deg2rad($angle_x));
12420: $tm[3] = 1;
12421: $tm[4] = -$tm[2] * $y;
12422: $tm[5] = -$tm[1] * $x;
12423:
12424: $this->Transform($tm);
12425: }
12426:
12427: 12428: 12429: 12430: 12431: 12432: 12433:
12434: protected function Transform($tm) {
12435: $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5]));
12436:
12437: $this->transfmatrix[$this->transfmatrix_key][] = array('a' => $tm[0], 'b' => $tm[1], 'c' => $tm[2], 'd' => $tm[3], 'e' => $tm[4], 'f' => $tm[5]);
12438:
12439: if ($this->inxobj) {
12440:
12441: if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) {
12442: $key = key($this->xobjects[$this->xobjid]['transfmrk']);
12443: $this->xobjects[$this->xobjid]['transfmrk'][$key] = strlen($this->xobjects[$this->xobjid]['outdata']);
12444: }
12445: } elseif (end($this->transfmrk[$this->page]) !== false) {
12446: $key = key($this->transfmrk[$this->page]);
12447: $this->transfmrk[$this->page][$key] = $this->pagelen[$this->page];
12448: }
12449: }
12450:
12451:
12452:
12453:
12454:
12455:
12456: 12457: 12458: 12459: 12460: 12461: 12462:
12463: public function SetLineWidth($width) {
12464:
12465: $this->LineWidth = $width;
12466: $this->linestyleWidth = sprintf('%.2F w', ($width * $this->k));
12467: if ($this->page > 0) {
12468: $this->_out($this->linestyleWidth);
12469: }
12470: }
12471:
12472: 12473: 12474: 12475: 12476: 12477: 12478:
12479: public function GetLineWidth() {
12480: return $this->LineWidth;
12481: }
12482:
12483: 12484: 12485: 12486: 12487: 12488: 12489: 12490: 12491: 12492: 12493: 12494: 12495: 12496: 12497: 12498: 12499: 12500: 12501: 12502: 12503: 12504: 12505:
12506: public function SetLineStyle($style, $ret=false) {
12507: $s = '';
12508: if (!is_array($style)) {
12509: return;
12510: }
12511: extract($style);
12512: if (isset($width)) {
12513: $this->LineWidth = $width;
12514: $this->linestyleWidth = sprintf('%.2F w', ($width * $this->k));
12515: $s .= $this->linestyleWidth.' ';
12516: }
12517: if (isset($cap)) {
12518: $ca = array('butt' => 0, 'round'=> 1, 'square' => 2);
12519: if (isset($ca[$cap])) {
12520: $this->linestyleCap = $ca[$cap].' J';
12521: $s .= $this->linestyleCap.' ';
12522: }
12523: }
12524: if (isset($join)) {
12525: $ja = array('miter' => 0, 'round' => 1, 'bevel' => 2);
12526: if (isset($ja[$join])) {
12527: $this->linestyleJoin = $ja[$join].' j';
12528: $s .= $this->linestyleJoin.' ';
12529: }
12530: }
12531: if (isset($dash)) {
12532: $dash_string = '';
12533: if ($dash) {
12534: if (preg_match('/^.+,/', $dash) > 0) {
12535: $tab = explode(',', $dash);
12536: } else {
12537: $tab = array($dash);
12538: }
12539: $dash_string = '';
12540: foreach ($tab as $i => $v) {
12541: if ($i) {
12542: $dash_string .= ' ';
12543: }
12544: $dash_string .= sprintf('%.2F', $v);
12545: }
12546: }
12547: if (!isset($phase) OR !$dash) {
12548: $phase = 0;
12549: }
12550: $this->linestyleDash = sprintf('[%s] %.2F d', $dash_string, $phase);
12551: $s .= $this->linestyleDash.' ';
12552: }
12553: if (isset($color)) {
12554: $s .= $this->SetDrawColorArray($color, true).' ';
12555: }
12556: if (!$ret) {
12557: $this->_out($s);
12558: }
12559: return $s;
12560: }
12561:
12562: 12563: 12564: 12565: 12566: 12567: 12568:
12569: protected function _outPoint($x, $y) {
12570: $this->_out(sprintf('%.2F %.2F m', $x * $this->k, ($this->h - $y) * $this->k));
12571: }
12572:
12573: 12574: 12575: 12576: 12577: 12578: 12579: 12580:
12581: protected function _outLine($x, $y) {
12582: $this->_out(sprintf('%.2F %.2F l', $x * $this->k, ($this->h - $y) * $this->k));
12583: }
12584:
12585: 12586: 12587: 12588: 12589: 12590: 12591: 12592: 12593: 12594:
12595: protected function _outRect($x, $y, $w, $h, $op) {
12596: $this->_out(sprintf('%.2F %.2F %.2F %.2F re %s', $x * $this->k, ($this->h - $y) * $this->k, $w * $this->k, -$h * $this->k, $op));
12597: }
12598:
12599: 12600: 12601: 12602: 12603: 12604: 12605: 12606: 12607: 12608: 12609: 12610:
12611: protected function _outCurve($x1, $y1, $x2, $y2, $x3, $y3) {
12612: $this->_out(sprintf('%.2F %.2F %.2F %.2F %.2F %.2F c', $x1 * $this->k, ($this->h - $y1) * $this->k, $x2 * $this->k, ($this->h - $y2) * $this->k, $x3 * $this->k, ($this->h - $y3) * $this->k));
12613: }
12614:
12615: 12616: 12617: 12618: 12619: 12620: 12621: 12622: 12623: 12624:
12625: protected function _outCurveV($x2, $y2, $x3, $y3) {
12626: $this->_out(sprintf('%.2F %.2F %.2F %.2F v', $x2 * $this->k, ($this->h - $y2) * $this->k, $x3 * $this->k, ($this->h - $y3) * $this->k));
12627: }
12628:
12629: 12630: 12631: 12632: 12633: 12634: 12635: 12636: 12637: 12638: 12639: 12640:
12641: protected function _outCurveY($x1, $y1, $x3, $y3) {
12642: $this->_out(sprintf('%.2F %.2F %.2F %.2F y', $x1 * $this->k, ($this->h - $y1) * $this->k, $x3 * $this->k, ($this->h - $y3) * $this->k));
12643: }
12644:
12645: 12646: 12647: 12648: 12649: 12650: 12651: 12652: 12653: 12654: 12655:
12656: public function Line($x1, $y1, $x2, $y2, $style=array()) {
12657: if (is_array($style)) {
12658: $this->SetLineStyle($style);
12659: }
12660: $this->_outPoint($x1, $y1);
12661: $this->_outLine($x2, $y2);
12662: $this->_out('S');
12663: }
12664:
12665: 12666: 12667: 12668: 12669: 12670: 12671: 12672: 12673: 12674: 12675: 12676: 12677: 12678: 12679: 12680: 12681: 12682: 12683:
12684: public function Rect($x, $y, $w, $h, $style='', $border_style=array(), $fill_color=array()) {
12685: if (!(false === strpos($style, 'F')) AND !empty($fill_color)) {
12686: $this->SetFillColorArray($fill_color);
12687: }
12688: $op = $this->getPathPaintOperator($style);
12689: if ((!$border_style) OR (isset($border_style['all']))) {
12690: if (isset($border_style['all']) AND $border_style['all']) {
12691: $this->SetLineStyle($border_style['all']);
12692: $border_style = array();
12693: }
12694: }
12695: $this->_outRect($x, $y, $w, $h, $op);
12696: if ($border_style) {
12697: $border_style2 = array();
12698: foreach ($border_style as $line => $value) {
12699: $length = strlen($line);
12700: for ($i = 0; $i < $length; ++$i) {
12701: $border_style2[$line[$i]] = $value;
12702: }
12703: }
12704: $border_style = $border_style2;
12705: if (isset($border_style['L']) AND $border_style['L']) {
12706: $this->Line($x, $y, $x, $y + $h, $border_style['L']);
12707: }
12708: if (isset($border_style['T']) AND $border_style['T']) {
12709: $this->Line($x, $y, $x + $w, $y, $border_style['T']);
12710: }
12711: if (isset($border_style['R']) AND $border_style['R']) {
12712: $this->Line($x + $w, $y, $x + $w, $y + $h, $border_style['R']);
12713: }
12714: if (isset($border_style['B']) AND $border_style['B']) {
12715: $this->Line($x, $y + $h, $x + $w, $y + $h, $border_style['B']);
12716: }
12717: }
12718: }
12719:
12720: 12721: 12722: 12723: 12724: 12725: 12726: 12727: 12728: 12729: 12730: 12731: 12732: 12733: 12734: 12735: 12736: 12737: 12738:
12739: public function Curve($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3, $style='', $line_style=array(), $fill_color=array()) {
12740: if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
12741: $this->SetFillColorArray($fill_color);
12742: }
12743: $op = $this->getPathPaintOperator($style);
12744: if ($line_style) {
12745: $this->SetLineStyle($line_style);
12746: }
12747: $this->_outPoint($x0, $y0);
12748: $this->_outCurve($x1, $y1, $x2, $y2, $x3, $y3);
12749: $this->_out($op);
12750: }
12751:
12752: 12753: 12754: 12755: 12756: 12757: 12758: 12759: 12760: 12761: 12762: 12763: 12764: 12765:
12766: public function Polycurve($x0, $y0, $segments, $style='', $line_style=array(), $fill_color=array()) {
12767: if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
12768: $this->SetFillColorArray($fill_color);
12769: }
12770: $op = $this->getPathPaintOperator($style);
12771: if ($op == 'f') {
12772: $line_style = array();
12773: }
12774: if ($line_style) {
12775: $this->SetLineStyle($line_style);
12776: }
12777: $this->_outPoint($x0, $y0);
12778: foreach ($segments as $segment) {
12779: list($x1, $y1, $x2, $y2, $x3, $y3) = $segment;
12780: $this->_outCurve($x1, $y1, $x2, $y2, $x3, $y3);
12781: }
12782: $this->_out($op);
12783: }
12784:
12785: 12786: 12787: 12788: 12789: 12790: 12791: 12792: 12793: 12794: 12795: 12796: 12797: 12798: 12799: 12800: 12801: 12802:
12803: public function Ellipse($x0, $y0, $rx, $ry='', $angle=0, $astart=0, $afinish=360, $style='', $line_style=array(), $fill_color=array(), $nc=2) {
12804: if ($this->empty_string($ry) OR ($ry == 0)) {
12805: $ry = $rx;
12806: }
12807: if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
12808: $this->SetFillColorArray($fill_color);
12809: }
12810: $op = $this->getPathPaintOperator($style);
12811: if ($op == 'f') {
12812: $line_style = array();
12813: }
12814: if ($line_style) {
12815: $this->SetLineStyle($line_style);
12816: }
12817: $this->_outellipticalarc($x0, $y0, $rx, $ry, $angle, $astart, $afinish, false, $nc);
12818: $this->_out($op);
12819: }
12820:
12821: 12822: 12823: 12824: 12825: 12826: 12827: 12828: 12829: 12830: 12831: 12832: 12833: 12834: 12835: 12836:
12837: protected function _outellipticalarc($xc, $yc, $rx, $ry, $xang=0, $angs=0, $angf=360, $pie=false, $nc=2) {
12838: $k = $this->k;
12839: if ($nc < 2) {
12840: $nc = 2;
12841: }
12842: if ($pie) {
12843:
12844: $this->_outPoint($xc, $yc);
12845: }
12846: $xang = deg2rad((float) $xang);
12847: $angs = deg2rad((float) $angs);
12848: $angf = deg2rad((float) $angf);
12849: $as = atan2((sin($angs) / $ry), (cos($angs) / $rx));
12850: $af = atan2((sin($angf) / $ry), (cos($angf) / $rx));
12851: if ($as < 0) {
12852: $as += (2 * M_PI);
12853: }
12854: if ($af < 0) {
12855: $af += (2 * M_PI);
12856: }
12857: if ($as > $af) {
12858:
12859: $as -= (2 * M_PI);
12860: }
12861: $total_angle = ($af - $as);
12862: if ($nc < 2) {
12863: $nc = 2;
12864: }
12865:
12866: $nc *= (2 * abs($total_angle) / M_PI);
12867: $nc = round($nc) + 1;
12868:
12869: $arcang = $total_angle / $nc;
12870:
12871: $x0 = $xc;
12872: $y0 = ($this->h - $yc);
12873:
12874: $ang = $as;
12875: $alpha = sin($arcang) * ((sqrt(4 + (3 * pow(tan(($arcang) / 2), 2))) - 1) / 3);
12876: $cos_xang = cos($xang);
12877: $sin_xang = sin($xang);
12878: $cos_ang = cos($ang);
12879: $sin_ang = sin($ang);
12880:
12881: $px1 = $x0 + ($rx * $cos_xang * $cos_ang) - ($ry * $sin_xang * $sin_ang);
12882: $py1 = $y0 + ($rx * $sin_xang * $cos_ang) + ($ry * $cos_xang * $sin_ang);
12883:
12884: $qx1 = ($alpha * ((-$rx * $cos_xang * $sin_ang) - ($ry * $sin_xang * $cos_ang)));
12885: $qy1 = ($alpha * ((-$rx * $sin_xang * $sin_ang) + ($ry * $cos_xang * $cos_ang)));
12886: if ($pie) {
12887: $this->_outLine($px1, $this->h - $py1);
12888: } else {
12889: $this->_outPoint($px1, $this->h - $py1);
12890: }
12891:
12892: for ($i = 1; $i <= $nc; ++$i) {
12893:
12894: $ang = $as + ($i * $arcang);
12895: $cos_xang = cos($xang);
12896: $sin_xang = sin($xang);
12897: $cos_ang = cos($ang);
12898: $sin_ang = sin($ang);
12899:
12900: $px2 = $x0 + ($rx * $cos_xang * $cos_ang) - ($ry * $sin_xang * $sin_ang);
12901: $py2 = $y0 + ($rx * $sin_xang * $cos_ang) + ($ry * $cos_xang * $sin_ang);
12902:
12903: $qx2 = ($alpha * ((-$rx * $cos_xang * $sin_ang) - ($ry * $sin_xang * $cos_ang)));
12904: $qy2 = ($alpha * ((-$rx * $sin_xang * $sin_ang) + ($ry * $cos_xang * $cos_ang)));
12905:
12906: $this->_outCurve(($px1 + $qx1), ($this->h - ($py1 + $qy1)), ($px2 - $qx2), ($this->h - ($py2 - $qy2)), $px2, ($this->h - $py2));
12907:
12908: $px1 = $px2;
12909: $py1 = $py2;
12910: $qx1 = $qx2;
12911: $qy1 = $qy2;
12912: }
12913: if ($pie) {
12914: $this->_outLine($xc, $yc);
12915: }
12916: }
12917:
12918: 12919: 12920: 12921: 12922: 12923: 12924: 12925: 12926: 12927: 12928: 12929: 12930: 12931: 12932:
12933: public function Circle($x0, $y0, $r, $angstr=0, $angend=360, $style='', $line_style=array(), $fill_color=array(), $nc=2) {
12934: $this->Ellipse($x0, $y0, $r, $r, 0, $angstr, $angend, $style, $line_style, $fill_color, $nc);
12935: }
12936:
12937: 12938: 12939: 12940: 12941: 12942: 12943: 12944: 12945: 12946: 12947: 12948: 12949: 12950: 12951:
12952: public function PolyLine($p, $style='', $line_style=array(), $fill_color=array()) {
12953: $this->Polygon($p, $style, $line_style, $fill_color, false);
12954: }
12955:
12956: 12957: 12958: 12959: 12960: 12961: 12962: 12963: 12964: 12965: 12966: 12967: 12968: 12969: 12970:
12971: public function Polygon($p, $style='', $line_style=array(), $fill_color=array(), $closed=true) {
12972: $nc = count($p);
12973: $np = $nc / 2;
12974: if ($closed) {
12975:
12976: for ($i = 0; $i < 4; ++$i) {
12977: $p[$nc + $i] = $p[$i];
12978: }
12979:
12980: if (isset($line_style[0])) {
12981: $line_style[$np] = $line_style[0];
12982: }
12983: $nc += 4;
12984: }
12985: if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
12986: $this->SetFillColorArray($fill_color);
12987: }
12988: $op = $this->getPathPaintOperator($style);
12989: if ($op == 'f') {
12990: $line_style = array();
12991: }
12992: $draw = true;
12993: if ($line_style) {
12994: if (isset($line_style['all'])) {
12995: $this->SetLineStyle($line_style['all']);
12996: } else {
12997: $draw = false;
12998: if ($op == 'B') {
12999:
13000: $op = 'f';
13001: $this->_outPoint($p[0], $p[1]);
13002: for ($i = 2; $i < $nc; $i = $i + 2) {
13003: $this->_outLine($p[$i], $p[$i + 1]);
13004: }
13005: $this->_out($op);
13006: }
13007:
13008: $this->_outPoint($p[0], $p[1]);
13009: for ($i = 2; $i < $nc; $i = $i + 2) {
13010: $line_num = ($i / 2) - 1;
13011: if (isset($line_style[$line_num])) {
13012: if ($line_style[$line_num] != 0) {
13013: if (is_array($line_style[$line_num])) {
13014: $this->_out('S');
13015: $this->SetLineStyle($line_style[$line_num]);
13016: $this->_outPoint($p[$i - 2], $p[$i - 1]);
13017: $this->_outLine($p[$i], $p[$i + 1]);
13018: $this->_out('S');
13019: $this->_outPoint($p[$i], $p[$i + 1]);
13020: } else {
13021: $this->_outLine($p[$i], $p[$i + 1]);
13022: }
13023: }
13024: } else {
13025: $this->_outLine($p[$i], $p[$i + 1]);
13026: }
13027: }
13028: $this->_out($op);
13029: }
13030: }
13031: if ($draw) {
13032: $this->_outPoint($p[0], $p[1]);
13033: for ($i = 2; $i < $nc; $i = $i + 2) {
13034: $this->_outLine($p[$i], $p[$i + 1]);
13035: }
13036: $this->_out($op);
13037: }
13038: }
13039:
13040: 13041: 13042: 13043: 13044: 13045: 13046: 13047: 13048: 13049: 13050: 13051: 13052: 13053: 13054: 13055: 13056: 13057: 13058: 13059: 13060: 13061: 13062: 13063: 13064: 13065: 13066: 13067: 13068:
13069: public function RegularPolygon($x0, $y0, $r, $ns, $angle=0, $draw_circle=false, $style='', $line_style=array(), $fill_color=array(), $circle_style='', $circle_outLine_style=array(), $circle_fill_color=array()) {
13070: if (3 > $ns) {
13071: $ns = 3;
13072: }
13073: if ($draw_circle) {
13074: $this->Circle($x0, $y0, $r, 0, 360, $circle_style, $circle_outLine_style, $circle_fill_color);
13075: }
13076: $p = array();
13077: for ($i = 0; $i < $ns; ++$i) {
13078: $a = $angle + ($i * 360 / $ns);
13079: $a_rad = deg2rad((float) $a);
13080: $p[] = $x0 + ($r * sin($a_rad));
13081: $p[] = $y0 + ($r * cos($a_rad));
13082: }
13083: $this->Polygon($p, $style, $line_style, $fill_color);
13084: }
13085:
13086: 13087: 13088: 13089: 13090: 13091: 13092: 13093: 13094: 13095: 13096: 13097: 13098: 13099: 13100: 13101: 13102: 13103: 13104: 13105: 13106: 13107: 13108: 13109: 13110: 13111: 13112: 13113: 13114: 13115: 13116:
13117: public function StarPolygon($x0, $y0, $r, $nv, $ng, $angle=0, $draw_circle=false, $style='', $line_style=array(), $fill_color=array(), $circle_style='', $circle_outLine_style=array(), $circle_fill_color=array()) {
13118: if ($nv < 2) {
13119: $nv = 2;
13120: }
13121: if ($draw_circle) {
13122: $this->Circle($x0, $y0, $r, 0, 360, $circle_style, $circle_outLine_style, $circle_fill_color);
13123: }
13124: $p2 = array();
13125: $visited = array();
13126: for ($i = 0; $i < $nv; ++$i) {
13127: $a = $angle + ($i * 360 / $nv);
13128: $a_rad = deg2rad((float) $a);
13129: $p2[] = $x0 + ($r * sin($a_rad));
13130: $p2[] = $y0 + ($r * cos($a_rad));
13131: $visited[] = false;
13132: }
13133: $p = array();
13134: $i = 0;
13135: do {
13136: $p[] = $p2[$i * 2];
13137: $p[] = $p2[($i * 2) + 1];
13138: $visited[$i] = true;
13139: $i += $ng;
13140: $i %= $nv;
13141: } while (!$visited[$i]);
13142: $this->Polygon($p, $style, $line_style, $fill_color);
13143: }
13144:
13145: 13146: 13147: 13148: 13149: 13150: 13151: 13152: 13153: 13154: 13155: 13156: 13157: 13158:
13159: public function RoundedRect($x, $y, $w, $h, $r, $round_corner='1111', $style='', $border_style=array(), $fill_color=array()) {
13160: $this->RoundedRectXY($x, $y, $w, $h, $r, $r, $round_corner, $style, $border_style, $fill_color);
13161: }
13162:
13163: 13164: 13165: 13166: 13167: 13168: 13169: 13170: 13171: 13172: 13173: 13174: 13175: 13176: 13177:
13178: public function RoundedRectXY($x, $y, $w, $h, $rx, $ry, $round_corner='1111', $style='', $border_style=array(), $fill_color=array()) {
13179: if (($round_corner == '0000') OR (($rx == $ry) AND ($rx == 0))) {
13180:
13181: $this->Rect($x, $y, $w, $h, $style, $border_style, $fill_color);
13182: return;
13183: }
13184:
13185: if (!(false === strpos($style, 'F')) AND isset($fill_color)) {
13186: $this->SetFillColorArray($fill_color);
13187: }
13188: $op = $this->getPathPaintOperator($style);
13189: if ($op == 'f') {
13190: $border_style = array();
13191: }
13192: if ($border_style) {
13193: $this->SetLineStyle($border_style);
13194: }
13195: $MyArc = 4 / 3 * (sqrt(2) - 1);
13196: $this->_outPoint($x + $rx, $y);
13197: $xc = $x + $w - $rx;
13198: $yc = $y + $ry;
13199: $this->_outLine($xc, $y);
13200: if ($round_corner[0]) {
13201: $this->_outCurve($xc + ($rx * $MyArc), $yc - $ry, $xc + $rx, $yc - ($ry * $MyArc), $xc + $rx, $yc);
13202: } else {
13203: $this->_outLine($x + $w, $y);
13204: }
13205: $xc = $x + $w - $rx;
13206: $yc = $y + $h - $ry;
13207: $this->_outLine($x + $w, $yc);
13208: if ($round_corner[1]) {
13209: $this->_outCurve($xc + $rx, $yc + ($ry * $MyArc), $xc + ($rx * $MyArc), $yc + $ry, $xc, $yc + $ry);
13210: } else {
13211: $this->_outLine($x + $w, $y + $h);
13212: }
13213: $xc = $x + $rx;
13214: $yc = $y + $h - $ry;
13215: $this->_outLine($xc, $y + $h);
13216: if ($round_corner[2]) {
13217: $this->_outCurve($xc - ($rx * $MyArc), $yc + $ry, $xc - $rx, $yc + ($ry * $MyArc), $xc - $rx, $yc);
13218: } else {
13219: $this->_outLine($x, $y + $h);
13220: }
13221: $xc = $x + $rx;
13222: $yc = $y + $ry;
13223: $this->_outLine($x, $yc);
13224: if ($round_corner[3]) {
13225: $this->_outCurve($xc - $rx, $yc - ($ry * $MyArc), $xc - ($rx * $MyArc), $yc - $ry, $xc, $yc - $ry);
13226: } else {
13227: $this->_outLine($x, $y);
13228: $this->_outLine($x + $rx, $y);
13229: }
13230: $this->_out($op);
13231: }
13232:
13233: 13234: 13235: 13236: 13237: 13238: 13239: 13240: 13241: 13242: 13243: 13244:
13245: public function Arrow($x0, $y0, $x1, $y1, $head_style=0, $arm_size=5, $arm_angle=15) {
13246:
13247:
13248: $dir_angle = atan2(($y0 - $y1), ($x0 - $x1));
13249: if ($dir_angle < 0) {
13250: $dir_angle += (2 * M_PI);
13251: }
13252: $arm_angle = deg2rad($arm_angle);
13253: $sx1 = $x1;
13254: $sy1 = $y1;
13255: if ($head_style > 0) {
13256:
13257: $sx1 = $x1 + (($arm_size - $this->LineWidth) * cos($dir_angle));
13258: $sy1 = $y1 + (($arm_size - $this->LineWidth) * sin($dir_angle));
13259: }
13260:
13261: $this->Line($x0, $y0, $sx1, $sy1);
13262:
13263: $x2L = $x1 + ($arm_size * cos($dir_angle + $arm_angle));
13264: $y2L = $y1 + ($arm_size * sin($dir_angle + $arm_angle));
13265:
13266: $x2R = $x1 + ($arm_size * cos($dir_angle - $arm_angle));
13267: $y2R = $y1 + ($arm_size * sin($dir_angle - $arm_angle));
13268: $mode = 'D';
13269: $style = array();
13270: switch ($head_style) {
13271: case 0: {
13272:
13273: $mode = 'D';
13274: $style = array(1, 1, 0);
13275: break;
13276: }
13277: case 1: {
13278:
13279: $mode = 'D';
13280: break;
13281: }
13282: case 2: {
13283:
13284: $mode = 'DF';
13285: break;
13286: }
13287: case 3: {
13288:
13289: $mode = 'F';
13290: break;
13291: }
13292: }
13293: $this->Polygon(array($x2L, $y2L, $x1, $y1, $x2R, $y2R), $mode, $style, array());
13294: }
13295:
13296:
13297:
13298:
13299:
13300: 13301: 13302: 13303: 13304: 13305: 13306: 13307: 13308: 13309:
13310: protected function utf8StrRev($str, $setbom=false, $forcertl=false) {
13311: return $this->utf8StrArrRev($this->UTF8StringToArray($str), $str, $setbom, $forcertl);
13312: }
13313:
13314: 13315: 13316: 13317: 13318: 13319: 13320: 13321: 13322: 13323: 13324:
13325: protected function utf8StrArrRev($arr, $str='', $setbom=false, $forcertl=false) {
13326: return $this->arrUTF8ToUTF16BE($this->utf8Bidi($arr, $str, $forcertl), $setbom);
13327: }
13328:
13329: 13330: 13331: 13332: 13333: 13334: 13335: 13336: 13337: 13338:
13339: protected function utf8Bidi($ta, $str='', $forcertl=false) {
13340:
13341: $pel = 0;
13342:
13343: $maxlevel = 0;
13344: if ($this->empty_string($str)) {
13345:
13346: $str = $this->UTF8ArrSubString($ta);
13347: }
13348:
13349: if (preg_match($this->unicode->uni_RE_PATTERN_ARABIC, $str)) {
13350: $arabic = true;
13351: } else {
13352: $arabic = false;
13353: }
13354:
13355: if (!($forcertl OR $arabic OR preg_match($this->unicode->uni_RE_PATTERN_RTL, $str))) {
13356: return $ta;
13357: }
13358:
13359:
13360: $numchars = count($ta);
13361:
13362: if ($forcertl == 'R') {
13363: $pel = 1;
13364: } elseif ($forcertl == 'L') {
13365: $pel = 0;
13366: } else {
13367:
13368:
13369: for ($i=0; $i < $numchars; ++$i) {
13370: $type = $this->unicode->uni_type[$ta[$i]];
13371: if ($type == 'L') {
13372: $pel = 0;
13373: break;
13374: } elseif (($type == 'AL') OR ($type == 'R')) {
13375: $pel = 1;
13376: break;
13377: }
13378: }
13379: }
13380:
13381:
13382: $cel = $pel;
13383:
13384: $dos = 'N';
13385: $remember = array();
13386:
13387: $sor = $pel % 2 ? 'R' : 'L';
13388: $eor = $sor;
13389:
13390:
13391: $chardata = Array();
13392:
13393:
13394:
13395: for ($i=0; $i < $numchars; ++$i) {
13396: if ($ta[$i] == $this->unicode->uni_RLE) {
13397:
13398:
13399:
13400: $next_level = $cel + ($cel % 2) + 1;
13401: if ($next_level < 62) {
13402: $remember[] = array('num' => $this->unicode->uni_RLE, 'cel' => $cel, 'dos' => $dos);
13403: $cel = $next_level;
13404: $dos = 'N';
13405: $sor = $eor;
13406: $eor = $cel % 2 ? 'R' : 'L';
13407: }
13408: } elseif ($ta[$i] == $this->unicode->uni_LRE) {
13409:
13410:
13411:
13412: $next_level = $cel + 2 - ($cel % 2);
13413: if ( $next_level < 62 ) {
13414: $remember[] = array('num' => $this->unicode->uni_LRE, 'cel' => $cel, 'dos' => $dos);
13415: $cel = $next_level;
13416: $dos = 'N';
13417: $sor = $eor;
13418: $eor = $cel % 2 ? 'R' : 'L';
13419: }
13420: } elseif ($ta[$i] == $this->unicode->uni_RLO) {
13421:
13422:
13423:
13424: $next_level = $cel + ($cel % 2) + 1;
13425: if ($next_level < 62) {
13426: $remember[] = array('num' => $this->unicode->uni_RLO, 'cel' => $cel, 'dos' => $dos);
13427: $cel = $next_level;
13428: $dos = 'R';
13429: $sor = $eor;
13430: $eor = $cel % 2 ? 'R' : 'L';
13431: }
13432: } elseif ($ta[$i] == $this->unicode->uni_LRO) {
13433:
13434:
13435:
13436: $next_level = $cel + 2 - ($cel % 2);
13437: if ( $next_level < 62 ) {
13438: $remember[] = array('num' => $this->unicode->uni_LRO, 'cel' => $cel, 'dos' => $dos);
13439: $cel = $next_level;
13440: $dos = 'L';
13441: $sor = $eor;
13442: $eor = $cel % 2 ? 'R' : 'L';
13443: }
13444: } elseif ($ta[$i] == $this->unicode->uni_PDF) {
13445:
13446: if (count($remember)) {
13447: $last = count($remember ) - 1;
13448: if (($remember[$last]['num'] == $this->unicode->uni_RLE) OR
13449: ($remember[$last]['num'] == $this->unicode->uni_LRE) OR
13450: ($remember[$last]['num'] == $this->unicode->uni_RLO) OR
13451: ($remember[$last]['num'] == $this->unicode->uni_LRO)) {
13452: $match = array_pop($remember);
13453: $cel = $match['cel'];
13454: $dos = $match['dos'];
13455: $sor = $eor;
13456: $eor = ($cel > $match['cel'] ? $cel : $match['cel']) % 2 ? 'R' : 'L';
13457: }
13458: }
13459: } elseif (($ta[$i] != $this->unicode->uni_RLE) AND
13460: ($ta[$i] != $this->unicode->uni_LRE) AND
13461: ($ta[$i] != $this->unicode->uni_RLO) AND
13462: ($ta[$i] != $this->unicode->uni_LRO) AND
13463: ($ta[$i] != $this->unicode->uni_PDF)) {
13464:
13465:
13466:
13467: if ($dos != 'N') {
13468: $chardir = $dos;
13469: } else {
13470: if (isset($this->unicode->uni_type[$ta[$i]])) {
13471: $chardir = $this->unicode->uni_type[$ta[$i]];
13472: } else {
13473: $chardir = 'L';
13474: }
13475: }
13476:
13477: $chardata[] = array('char' => $ta[$i], 'level' => $cel, 'type' => $chardir, 'sor' => $sor, 'eor' => $eor);
13478: }
13479: }
13480:
13481:
13482:
13483:
13484:
13485:
13486:
13487:
13488: $numchars = count($chardata);
13489:
13490:
13491: $prevlevel = -1;
13492: $levcount = 0;
13493: for ($i=0; $i < $numchars; ++$i) {
13494: if ($chardata[$i]['type'] == 'NSM') {
13495: if ($levcount) {
13496: $chardata[$i]['type'] = $chardata[$i]['sor'];
13497: } elseif ($i > 0) {
13498: $chardata[$i]['type'] = $chardata[($i-1)]['type'];
13499: }
13500: }
13501: if ($chardata[$i]['level'] != $prevlevel) {
13502: $levcount = 0;
13503: } else {
13504: ++$levcount;
13505: }
13506: $prevlevel = $chardata[$i]['level'];
13507: }
13508:
13509:
13510: $prevlevel = -1;
13511: $levcount = 0;
13512: for ($i=0; $i < $numchars; ++$i) {
13513: if ($chardata[$i]['char'] == 'EN') {
13514: for ($j=$levcount; $j >= 0; $j--) {
13515: if ($chardata[$j]['type'] == 'AL') {
13516: $chardata[$i]['type'] = 'AN';
13517: } elseif (($chardata[$j]['type'] == 'L') OR ($chardata[$j]['type'] == 'R')) {
13518: break;
13519: }
13520: }
13521: }
13522: if ($chardata[$i]['level'] != $prevlevel) {
13523: $levcount = 0;
13524: } else {
13525: ++$levcount;
13526: }
13527: $prevlevel = $chardata[$i]['level'];
13528: }
13529:
13530:
13531: for ($i=0; $i < $numchars; ++$i) {
13532: if ($chardata[$i]['type'] == 'AL') {
13533: $chardata[$i]['type'] = 'R';
13534: }
13535: }
13536:
13537:
13538: $prevlevel = -1;
13539: $levcount = 0;
13540: for ($i=0; $i < $numchars; ++$i) {
13541: if (($levcount > 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
13542: if (($chardata[$i]['type'] == 'ES') AND ($chardata[($i-1)]['type'] == 'EN') AND ($chardata[($i+1)]['type'] == 'EN')) {
13543: $chardata[$i]['type'] = 'EN';
13544: } elseif (($chardata[$i]['type'] == 'CS') AND ($chardata[($i-1)]['type'] == 'EN') AND ($chardata[($i+1)]['type'] == 'EN')) {
13545: $chardata[$i]['type'] = 'EN';
13546: } elseif (($chardata[$i]['type'] == 'CS') AND ($chardata[($i-1)]['type'] == 'AN') AND ($chardata[($i+1)]['type'] == 'AN')) {
13547: $chardata[$i]['type'] = 'AN';
13548: }
13549: }
13550: if ($chardata[$i]['level'] != $prevlevel) {
13551: $levcount = 0;
13552: } else {
13553: ++$levcount;
13554: }
13555: $prevlevel = $chardata[$i]['level'];
13556: }
13557:
13558:
13559: $prevlevel = -1;
13560: $levcount = 0;
13561: for ($i=0; $i < $numchars; ++$i) {
13562: if ($chardata[$i]['type'] == 'ET') {
13563: if (($levcount > 0) AND ($chardata[($i-1)]['type'] == 'EN')) {
13564: $chardata[$i]['type'] = 'EN';
13565: } else {
13566: $j = $i+1;
13567: while (($j < $numchars) AND ($chardata[$j]['level'] == $prevlevel)) {
13568: if ($chardata[$j]['type'] == 'EN') {
13569: $chardata[$i]['type'] = 'EN';
13570: break;
13571: } elseif ($chardata[$j]['type'] != 'ET') {
13572: break;
13573: }
13574: ++$j;
13575: }
13576: }
13577: }
13578: if ($chardata[$i]['level'] != $prevlevel) {
13579: $levcount = 0;
13580: } else {
13581: ++$levcount;
13582: }
13583: $prevlevel = $chardata[$i]['level'];
13584: }
13585:
13586:
13587: $prevlevel = -1;
13588: $levcount = 0;
13589: for ($i=0; $i < $numchars; ++$i) {
13590: if (($chardata[$i]['type'] == 'ET') OR ($chardata[$i]['type'] == 'ES') OR ($chardata[$i]['type'] == 'CS')) {
13591: $chardata[$i]['type'] = 'ON';
13592: }
13593: if ($chardata[$i]['level'] != $prevlevel) {
13594: $levcount = 0;
13595: } else {
13596: ++$levcount;
13597: }
13598: $prevlevel = $chardata[$i]['level'];
13599: }
13600:
13601:
13602: $prevlevel = -1;
13603: $levcount = 0;
13604: for ($i=0; $i < $numchars; ++$i) {
13605: if ($chardata[$i]['char'] == 'EN') {
13606: for ($j=$levcount; $j >= 0; $j--) {
13607: if ($chardata[$j]['type'] == 'L') {
13608: $chardata[$i]['type'] = 'L';
13609: } elseif ($chardata[$j]['type'] == 'R') {
13610: break;
13611: }
13612: }
13613: }
13614: if ($chardata[$i]['level'] != $prevlevel) {
13615: $levcount = 0;
13616: } else {
13617: ++$levcount;
13618: }
13619: $prevlevel = $chardata[$i]['level'];
13620: }
13621:
13622:
13623: $prevlevel = -1;
13624: $levcount = 0;
13625: for ($i=0; $i < $numchars; ++$i) {
13626: if (($levcount > 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
13627: if (($chardata[$i]['type'] == 'N') AND ($chardata[($i-1)]['type'] == 'L') AND ($chardata[($i+1)]['type'] == 'L')) {
13628: $chardata[$i]['type'] = 'L';
13629: } elseif (($chardata[$i]['type'] == 'N') AND
13630: (($chardata[($i-1)]['type'] == 'R') OR ($chardata[($i-1)]['type'] == 'EN') OR ($chardata[($i-1)]['type'] == 'AN')) AND
13631: (($chardata[($i+1)]['type'] == 'R') OR ($chardata[($i+1)]['type'] == 'EN') OR ($chardata[($i+1)]['type'] == 'AN'))) {
13632: $chardata[$i]['type'] = 'R';
13633: } elseif ($chardata[$i]['type'] == 'N') {
13634:
13635: $chardata[$i]['type'] = $chardata[$i]['sor'];
13636: }
13637: } elseif (($levcount == 0) AND (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] == $prevlevel)) {
13638:
13639: if (($chardata[$i]['type'] == 'N') AND ($chardata[$i]['sor'] == 'L') AND ($chardata[($i+1)]['type'] == 'L')) {
13640: $chardata[$i]['type'] = 'L';
13641: } elseif (($chardata[$i]['type'] == 'N') AND
13642: (($chardata[$i]['sor'] == 'R') OR ($chardata[$i]['sor'] == 'EN') OR ($chardata[$i]['sor'] == 'AN')) AND
13643: (($chardata[($i+1)]['type'] == 'R') OR ($chardata[($i+1)]['type'] == 'EN') OR ($chardata[($i+1)]['type'] == 'AN'))) {
13644: $chardata[$i]['type'] = 'R';
13645: } elseif ($chardata[$i]['type'] == 'N') {
13646:
13647: $chardata[$i]['type'] = $chardata[$i]['sor'];
13648: }
13649: } elseif (($levcount > 0) AND ((($i+1) == $numchars) OR (($i+1) < $numchars) AND ($chardata[($i+1)]['level'] != $prevlevel))) {
13650:
13651: if (($chardata[$i]['type'] == 'N') AND ($chardata[($i-1)]['type'] == 'L') AND ($chardata[$i]['eor'] == 'L')) {
13652: $chardata[$i]['type'] = 'L';
13653: } elseif (($chardata[$i]['type'] == 'N') AND
13654: (($chardata[($i-1)]['type'] == 'R') OR ($chardata[($i-1)]['type'] == 'EN') OR ($chardata[($i-1)]['type'] == 'AN')) AND
13655: (($chardata[$i]['eor'] == 'R') OR ($chardata[$i]['eor'] == 'EN') OR ($chardata[$i]['eor'] == 'AN'))) {
13656: $chardata[$i]['type'] = 'R';
13657: } elseif ($chardata[$i]['type'] == 'N') {
13658:
13659: $chardata[$i]['type'] = $chardata[$i]['sor'];
13660: }
13661: } elseif ($chardata[$i]['type'] == 'N') {
13662:
13663: $chardata[$i]['type'] = $chardata[$i]['sor'];
13664: }
13665: if ($chardata[$i]['level'] != $prevlevel) {
13666: $levcount = 0;
13667: } else {
13668: ++$levcount;
13669: }
13670: $prevlevel = $chardata[$i]['level'];
13671: }
13672:
13673:
13674:
13675: for ($i=0; $i < $numchars; ++$i) {
13676: $odd = $chardata[$i]['level'] % 2;
13677: if ($odd) {
13678: if (($chardata[$i]['type'] == 'L') OR ($chardata[$i]['type'] == 'AN') OR ($chardata[$i]['type'] == 'EN')) {
13679: $chardata[$i]['level'] += 1;
13680: }
13681: } else {
13682: if ($chardata[$i]['type'] == 'R') {
13683: $chardata[$i]['level'] += 1;
13684: } elseif (($chardata[$i]['type'] == 'AN') OR ($chardata[$i]['type'] == 'EN')) {
13685: $chardata[$i]['level'] += 2;
13686: }
13687: }
13688: $maxlevel = max($chardata[$i]['level'],$maxlevel);
13689: }
13690:
13691:
13692:
13693:
13694:
13695:
13696: for ($i=0; $i < $numchars; ++$i) {
13697: if (($chardata[$i]['type'] == 'B') OR ($chardata[$i]['type'] == 'S')) {
13698: $chardata[$i]['level'] = $pel;
13699: } elseif ($chardata[$i]['type'] == 'WS') {
13700: $j = $i+1;
13701: while ($j < $numchars) {
13702: if ((($chardata[$j]['type'] == 'B') OR ($chardata[$j]['type'] == 'S')) OR
13703: (($j == ($numchars-1)) AND ($chardata[$j]['type'] == 'WS'))) {
13704: $chardata[$i]['level'] = $pel;
13705: break;
13706: } elseif ($chardata[$j]['type'] != 'WS') {
13707: break;
13708: }
13709: ++$j;
13710: }
13711: }
13712: }
13713:
13714:
13715:
13716: if ($arabic) {
13717: $endedletter = array(1569,1570,1571,1572,1573,1575,1577,1583,1584,1585,1586,1608,1688);
13718: $alfletter = array(1570,1571,1573,1575);
13719: $chardata2 = $chardata;
13720: $laaletter = false;
13721: $charAL = array();
13722: $x = 0;
13723: for ($i=0; $i < $numchars; ++$i) {
13724: if (($this->unicode->uni_type[$chardata[$i]['char']] == 'AL') OR ($chardata[$i]['char'] == 32) OR ($chardata[$i]['char'] == 8204)) {
13725: $charAL[$x] = $chardata[$i];
13726: $charAL[$x]['i'] = $i;
13727: $chardata[$i]['x'] = $x;
13728: ++$x;
13729: }
13730: }
13731: $numAL = $x;
13732: for ($i=0; $i < $numchars; ++$i) {
13733: $thischar = $chardata[$i];
13734: if ($i > 0) {
13735: $prevchar = $chardata[($i-1)];
13736: } else {
13737: $prevchar = false;
13738: }
13739: if (($i+1) < $numchars) {
13740: $nextchar = $chardata[($i+1)];
13741: } else {
13742: $nextchar = false;
13743: }
13744: if ($this->unicode->uni_type[$thischar['char']] == 'AL') {
13745: $x = $thischar['x'];
13746: if ($x > 0) {
13747: $prevchar = $charAL[($x-1)];
13748: } else {
13749: $prevchar = false;
13750: }
13751: if (($x+1) < $numAL) {
13752: $nextchar = $charAL[($x+1)];
13753: } else {
13754: $nextchar = false;
13755: }
13756:
13757: if (($prevchar !== false) AND ($prevchar['char'] == 1604) AND (in_array($thischar['char'], $alfletter))) {
13758: $arabicarr = $this->unicode->uni_laa_array;
13759: $laaletter = true;
13760: if ($x > 1) {
13761: $prevchar = $charAL[($x-2)];
13762: } else {
13763: $prevchar = false;
13764: }
13765: } else {
13766: $arabicarr = $this->unicode->uni_arabicsubst;
13767: $laaletter = false;
13768: }
13769: if (($prevchar !== false) AND ($nextchar !== false) AND
13770: (($this->unicode->uni_type[$prevchar['char']] == 'AL') OR ($this->unicode->uni_type[$prevchar['char']] == 'NSM')) AND
13771: (($this->unicode->uni_type[$nextchar['char']] == 'AL') OR ($this->unicode->uni_type[$nextchar['char']] == 'NSM')) AND
13772: ($prevchar['type'] == $thischar['type']) AND
13773: ($nextchar['type'] == $thischar['type']) AND
13774: ($nextchar['char'] != 1567)) {
13775: if (in_array($prevchar['char'], $endedletter)) {
13776: if (isset($arabicarr[$thischar['char']][2])) {
13777:
13778: $chardata2[$i]['char'] = $arabicarr[$thischar['char']][2];
13779: }
13780: } else {
13781: if (isset($arabicarr[$thischar['char']][3])) {
13782:
13783: $chardata2[$i]['char'] = $arabicarr[$thischar['char']][3];
13784: }
13785: }
13786: } elseif (($nextchar !== false) AND
13787: (($this->unicode->uni_type[$nextchar['char']] == 'AL') OR ($this->unicode->uni_type[$nextchar['char']] == 'NSM')) AND
13788: ($nextchar['type'] == $thischar['type']) AND
13789: ($nextchar['char'] != 1567)) {
13790: if (isset($arabicarr[$chardata[$i]['char']][2])) {
13791:
13792: $chardata2[$i]['char'] = $arabicarr[$thischar['char']][2];
13793: }
13794: } elseif ((($prevchar !== false) AND
13795: (($this->unicode->uni_type[$prevchar['char']] == 'AL') OR ($this->unicode->uni_type[$prevchar['char']] == 'NSM')) AND
13796: ($prevchar['type'] == $thischar['type'])) OR
13797: (($nextchar !== false) AND ($nextchar['char'] == 1567))) {
13798:
13799: if (($i > 1) AND ($thischar['char'] == 1607) AND
13800: ($chardata[$i-1]['char'] == 1604) AND
13801: ($chardata[$i-2]['char'] == 1604)) {
13802:
13803:
13804: $chardata2[$i-2]['char'] = false;
13805: $chardata2[$i-1]['char'] = false;
13806: $chardata2[$i]['char'] = 65010;
13807: } else {
13808: if (($prevchar !== false) AND in_array($prevchar['char'], $endedletter)) {
13809: if (isset($arabicarr[$thischar['char']][0])) {
13810:
13811: $chardata2[$i]['char'] = $arabicarr[$thischar['char']][0];
13812: }
13813: } else {
13814: if (isset($arabicarr[$thischar['char']][1])) {
13815:
13816: $chardata2[$i]['char'] = $arabicarr[$thischar['char']][1];
13817: }
13818: }
13819: }
13820: } elseif (isset($arabicarr[$thischar['char']][0])) {
13821:
13822: $chardata2[$i]['char'] = $arabicarr[$thischar['char']][0];
13823: }
13824:
13825: if ($laaletter) {
13826:
13827: $chardata2[($charAL[($x-1)]['i'])]['char'] = false;
13828: }
13829: }
13830: }
13831: 13832: 13833: 13834:
13835: $cw = &$this->CurrentFont['cw'];
13836: for ($i = 0; $i < ($numchars-1); ++$i) {
13837: if (($chardata2[$i]['char'] == 1617) AND (isset($this->unicode->uni_diacritics[($chardata2[$i+1]['char'])]))) {
13838:
13839: if (isset($cw[($this->unicode->uni_diacritics[($chardata2[$i+1]['char'])])])) {
13840: $chardata2[$i]['char'] = false;
13841: $chardata2[$i+1]['char'] = $this->unicode->uni_diacritics[($chardata2[$i+1]['char'])];
13842: }
13843: }
13844: }
13845:
13846: foreach ($chardata2 as $key => $value) {
13847: if ($value['char'] === false) {
13848: unset($chardata2[$key]);
13849: }
13850: }
13851: $chardata = array_values($chardata2);
13852: $numchars = count($chardata);
13853: unset($chardata2);
13854: unset($arabicarr);
13855: unset($laaletter);
13856: unset($charAL);
13857: }
13858:
13859:
13860: for ($j=$maxlevel; $j > 0; $j--) {
13861: $ordarray = Array();
13862: $revarr = Array();
13863: $onlevel = false;
13864: for ($i=0; $i < $numchars; ++$i) {
13865: if ($chardata[$i]['level'] >= $j) {
13866: $onlevel = true;
13867: if (isset($this->unicode->uni_mirror[$chardata[$i]['char']])) {
13868:
13869: $chardata[$i]['char'] = $this->unicode->uni_mirror[$chardata[$i]['char']];
13870: }
13871: $revarr[] = $chardata[$i];
13872: } else {
13873: if ($onlevel) {
13874: $revarr = array_reverse($revarr);
13875: $ordarray = array_merge($ordarray, $revarr);
13876: $revarr = Array();
13877: $onlevel = false;
13878: }
13879: $ordarray[] = $chardata[$i];
13880: }
13881: }
13882: if ($onlevel) {
13883: $revarr = array_reverse($revarr);
13884: $ordarray = array_merge($ordarray, $revarr);
13885: }
13886: $chardata = $ordarray;
13887: }
13888:
13889: $ordarray = array();
13890: for ($i=0; $i < $numchars; ++$i) {
13891: $ordarray[] = $chardata[$i]['char'];
13892:
13893: $this->CurrentFont['subsetchars'][$chardata[$i]['char']] = true;
13894: }
13895:
13896: $this->setFontSubBuffer($this->CurrentFont['fontkey'], 'subsetchars', $this->CurrentFont['subsetchars']);
13897: return $ordarray;
13898: }
13899:
13900:
13901:
13902: 13903: 13904: 13905: 13906: 13907: 13908: 13909: 13910: 13911:
13912: public function Bookmark($txt, $level=0, $y=-1, $page='') {
13913: if ($level < 0) {
13914: $level = 0;
13915: }
13916: if (isset($this->outlines[0])) {
13917: $lastoutline = end($this->outlines);
13918: $maxlevel = $lastoutline['l'] + 1;
13919: } else {
13920: $maxlevel = 0;
13921: }
13922: if ($level > $maxlevel) {
13923: $level = $maxlevel;
13924: }
13925: if ($y == -1) {
13926: $y = $this->GetY();
13927: }
13928: if (empty($page)) {
13929: $page = $this->PageNo();
13930: if (empty($page)) {
13931: return;
13932: }
13933: }
13934: $this->outlines[] = array('t' => $txt, 'l' => $level, 'y' => $y, 'p' => $page);
13935: }
13936:
13937: 13938: 13939: 13940: 13941: 13942:
13943: protected function _putbookmarks() {
13944: $nb = count($this->outlines);
13945: if ($nb == 0) {
13946: return;
13947: }
13948:
13949: $outline_p = array();
13950: $outline_y = array();
13951: foreach ($this->outlines as $key => $row) {
13952: $outline_p[$key] = $row['p'];
13953: $outline_k[$key] = $key;
13954: }
13955:
13956: array_multisort($outline_p, SORT_NUMERIC, SORT_ASC, $outline_k, SORT_NUMERIC, SORT_ASC, $this->outlines);
13957: $lru = array();
13958: $level = 0;
13959: foreach ($this->outlines as $i => $o) {
13960: if ($o['l'] > 0) {
13961: $parent = $lru[($o['l'] - 1)];
13962:
13963: $this->outlines[$i]['parent'] = $parent;
13964: $this->outlines[$parent]['last'] = $i;
13965: if ($o['l'] > $level) {
13966:
13967: $this->outlines[$parent]['first'] = $i;
13968: }
13969: } else {
13970: $this->outlines[$i]['parent'] = $nb;
13971: }
13972: if (($o['l'] <= $level) AND ($i > 0)) {
13973:
13974: $prev = $lru[$o['l']];
13975: $this->outlines[$prev]['next'] = $i;
13976: $this->outlines[$i]['prev'] = $prev;
13977: }
13978: $lru[$o['l']] = $i;
13979: $level = $o['l'];
13980: }
13981:
13982: $n = $this->n + 1;
13983: $nltags = '/<br[\s]?\/>|<\/(blockquote|dd|dl|div|dt|h1|h2|h3|h4|h5|h6|hr|li|ol|p|pre|ul|tcpdf|table|tr|td)>/si';
13984: foreach ($this->outlines as $i => $o) {
13985: if (isset($this->page_obj_id[($o['p'])])) {
13986: $oid = $this->_newobj();
13987:
13988: $title = preg_replace($nltags, "\n", $o['t']);
13989: $title = preg_replace("/[\r]+/si", '', $title);
13990: $title = preg_replace("/[\n]+/si", "\n", $title);
13991: $title = strip_tags($title);
13992: $title = $this->stringTrim($title);
13993: $out = '<</Title '.$this->_textstring($title, $oid);
13994: $out .= ' /Parent '.($n + $o['parent']).' 0 R';
13995: if (isset($o['prev'])) {
13996: $out .= ' /Prev '.($n + $o['prev']).' 0 R';
13997: }
13998: if (isset($o['next'])) {
13999: $out .= ' /Next '.($n + $o['next']).' 0 R';
14000: }
14001: if (isset($o['first'])) {
14002: $out .= ' /First '.($n + $o['first']).' 0 R';
14003: }
14004: if (isset($o['last'])) {
14005: $out .= ' /Last '.($n + $o['last']).' 0 R';
14006: }
14007: $out .= ' '.sprintf('/Dest [%u 0 R /XYZ 0 %.2F null]', $this->page_obj_id[($o['p'])], ($this->pagedim[$o['p']]['h'] - ($o['y'] * $this->k)));
14008: $out .= ' /Count 0 >>';
14009: $out .= "\n".'endobj';
14010: $this->_out($out);
14011: }
14012: }
14013:
14014: $this->OutlineRoot = $this->_newobj();
14015: $this->_out('<< /Type /Outlines /First '.$n.' 0 R /Last '.($n + $lru[0]).' 0 R >>'."\n".'endobj');
14016: }
14017:
14018:
14019:
14020: 14021: 14022: 14023: 14024: 14025: 14026:
14027: public function IncludeJS($script) {
14028: $this->javascript .= $script;
14029: }
14030:
14031: 14032: 14033: 14034: 14035: 14036: 14037: 14038: 14039:
14040: public function addJavascriptObject($script, $onload=false) {
14041: ++$this->n;
14042: $this->js_objects[$this->n] = array('n' => $this->n, 'js' => $script, 'onload' => $onload);
14043: return $this->n;
14044: }
14045:
14046: 14047: 14048: 14049: 14050: 14051:
14052: protected function _putjavascript() {
14053: if (empty($this->javascript) AND empty($this->js_objects)) {
14054: return;
14055: }
14056: if (strpos($this->javascript, 'this.addField') > 0) {
14057: if (!$this->ur['enabled']) {
14058:
14059: }
14060:
14061:
14062: $jsa = sprintf("ftcpdfdocsaved=this.addField('%s','%s',%d,[%.2F,%.2F,%.2F,%.2F]);", 'tcpdfdocsaved', 'text', 0, 0, 1, 0, 1);
14063: $jsb = "getField('tcpdfdocsaved').value='saved';";
14064: $this->javascript = $jsa."\n".$this->javascript."\n".$jsb;
14065: }
14066: $this->n_js = $this->_newobj();
14067: $out = ' << /Names [';
14068: if (!empty($this->javascript)) {
14069: $out .= ' (EmbeddedJS) '.($this->n + 1).' 0 R';
14070: }
14071: if (!empty($this->js_objects)) {
14072: foreach ($this->js_objects as $key => $val) {
14073: if ($val['onload']) {
14074: $out .= ' (JS'.$key.') '.$key.' 0 R';
14075: }
14076: }
14077: }
14078: $out .= ' ] >>';
14079: $out .= "\n".'endobj';
14080: $this->_out($out);
14081:
14082: if (!empty($this->javascript)) {
14083: $obj_id = $this->_newobj();
14084: $out = '<< /S /JavaScript';
14085: $out .= ' /JS '.$this->_textstring($this->javascript, $obj_id);
14086: $out .= ' >>';
14087: $out .= "\n".'endobj';
14088: $this->_out($out);
14089: }
14090:
14091: if (!empty($this->js_objects)) {
14092: foreach ($this->js_objects as $key => $val) {
14093: $out = $this->_getobj($key)."\n".' << /S /JavaScript /JS '.$this->_textstring($val['js'], $key).' >>'."\n".'endobj';
14094: $this->_out($out);
14095: }
14096: }
14097: }
14098:
14099: 14100: 14101: 14102: 14103: 14104: 14105:
14106: protected function _JScolor($color) {
14107: static $aColors = array('transparent', 'black', 'white', 'red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'dkGray', 'gray', 'ltGray');
14108: if (substr($color,0,1) == '#') {
14109: return sprintf("['RGB',%.3F,%.3F,%.3F]", hexdec(substr($color,1,2))/255, hexdec(substr($color,3,2))/255, hexdec(substr($color,5,2))/255);
14110: }
14111: if (!in_array($color,$aColors)) {
14112: $this->Error('Invalid color: '.$color);
14113: }
14114: return 'color.'.$color;
14115: }
14116:
14117: 14118: 14119: 14120: 14121: 14122: 14123: 14124: 14125: 14126: 14127: 14128: 14129:
14130: protected function _addfield($type, $name, $x, $y, $w, $h, $prop) {
14131: if ($this->rtl) {
14132: $x = $x - $w;
14133: }
14134:
14135: $this->javascript .= "if(getField('tcpdfdocsaved').value != 'saved') {";
14136: $k = $this->k;
14137: $this->javascript .= sprintf("f".$name."=this.addField('%s','%s',%u,[%.2F,%.2F,%.2F,%.2F]);", $name, $type, $this->PageNo()-1, $x*$k, ($this->h-$y)*$k+1, ($x+$w)*$k, ($this->h-$y-$h)*$k+1)."\n";
14138: $this->javascript .= 'f'.$name.'.textSize='.$this->FontSizePt.";\n";
14139: while (list($key, $val) = each($prop)) {
14140: if (strcmp(substr($key, -5), 'Color') == 0) {
14141: $val = $this->_JScolor($val);
14142: } else {
14143: $val = "'".$val."'";
14144: }
14145: $this->javascript .= 'f'.$name.'.'.$key.'='.$val.";\n";
14146: }
14147: if ($this->rtl) {
14148: $this->x -= $w;
14149: } else {
14150: $this->x += $w;
14151: }
14152: $this->javascript .= '}';
14153: }
14154:
14155:
14156:
14157: 14158: 14159: 14160: 14161: 14162: 14163: 14164:
14165: protected function getAnnotOptFromJSProp($prop) {
14166: if (isset($prop['aopt']) AND is_array($prop['aopt'])) {
14167:
14168: return $prop['aopt'];
14169: }
14170: $opt = array();
14171:
14172: if (isset($prop['alignment'])) {
14173: switch ($prop['alignment']) {
14174: case 'left': {
14175: $opt['q'] = 0;
14176: break;
14177: }
14178: case 'center': {
14179: $opt['q'] = 1;
14180: break;
14181: }
14182: case 'right': {
14183: $opt['q'] = 2;
14184: break;
14185: }
14186: default: {
14187: $opt['q'] = ($this->rtl)?2:0;
14188: break;
14189: }
14190: }
14191: }
14192:
14193: if (isset($prop['lineWidth'])) {
14194: $linewidth = intval($prop['lineWidth']);
14195: } else {
14196: $linewidth = 1;
14197: }
14198:
14199: if (isset($prop['borderStyle'])) {
14200: switch ($prop['borderStyle']) {
14201: case 'border.d':
14202: case 'dashed': {
14203: $opt['border'] = array(0, 0, $linewidth, array(3, 2));
14204: $opt['bs'] = array('w'=>$linewidth, 's'=>'D', 'd'=>array(3, 2));
14205: break;
14206: }
14207: case 'border.b':
14208: case 'beveled': {
14209: $opt['border'] = array(0, 0, $linewidth);
14210: $opt['bs'] = array('w'=>$linewidth, 's'=>'B');
14211: break;
14212: }
14213: case 'border.i':
14214: case 'inset': {
14215: $opt['border'] = array(0, 0, $linewidth);
14216: $opt['bs'] = array('w'=>$linewidth, 's'=>'I');
14217: break;
14218: }
14219: case 'border.u':
14220: case 'underline': {
14221: $opt['border'] = array(0, 0, $linewidth);
14222: $opt['bs'] = array('w'=>$linewidth, 's'=>'U');
14223: break;
14224: }
14225: default:
14226: case 'border.s':
14227: case 'solid': {
14228: $opt['border'] = array(0, 0, $linewidth);
14229: $opt['bs'] = array('w'=>$linewidth, 's'=>'S');
14230: break;
14231: }
14232: }
14233: }
14234: if (isset($prop['border']) AND is_array($prop['border'])) {
14235: $opt['border'] = $prop['border'];
14236: }
14237: if (!isset($opt['mk'])) {
14238: $opt['mk'] = array();
14239: }
14240: if (!isset($opt['mk']['if'])) {
14241: $opt['mk']['if'] = array();
14242: }
14243: $opt['mk']['if']['a'] = array(0.5, 0.5);
14244:
14245: if (isset($prop['buttonAlignX'])) {
14246: $opt['mk']['if']['a'][0] = $prop['buttonAlignX'];
14247: }
14248:
14249: if (isset($prop['buttonAlignY'])) {
14250: $opt['mk']['if']['a'][1] = $prop['buttonAlignY'];
14251: }
14252:
14253: if (isset($prop['buttonFitBounds']) AND ($prop['buttonFitBounds'] == 'true')) {
14254: $opt['mk']['if']['fb'] = true;
14255: }
14256:
14257: if (isset($prop['buttonScaleHow'])) {
14258: switch ($prop['buttonScaleHow']) {
14259: case 'scaleHow.proportional': {
14260: $opt['mk']['if']['s'] = 'P';
14261: break;
14262: }
14263: case 'scaleHow.anamorphic': {
14264: $opt['mk']['if']['s'] = 'A';
14265: break;
14266: }
14267: }
14268: }
14269:
14270: if (isset($prop['buttonScaleWhen'])) {
14271: switch ($prop['buttonScaleWhen']) {
14272: case 'scaleWhen.always': {
14273: $opt['mk']['if']['sw'] = 'A';
14274: break;
14275: }
14276: case 'scaleWhen.never': {
14277: $opt['mk']['if']['sw'] = 'N';
14278: break;
14279: }
14280: case 'scaleWhen.tooBig': {
14281: $opt['mk']['if']['sw'] = 'B';
14282: break;
14283: }
14284: case 'scaleWhen.tooSmall': {
14285: $opt['mk']['if']['sw'] = 'S';
14286: break;
14287: }
14288: }
14289: }
14290:
14291: if (isset($prop['buttonPosition'])) {
14292: switch ($prop['buttonPosition']) {
14293: case 0:
14294: case 'position.textOnly': {
14295: $opt['mk']['tp'] = 0;
14296: break;
14297: }
14298: case 1:
14299: case 'position.iconOnly': {
14300: $opt['mk']['tp'] = 1;
14301: break;
14302: }
14303: case 2:
14304: case 'position.iconTextV': {
14305: $opt['mk']['tp'] = 2;
14306: break;
14307: }
14308: case 3:
14309: case 'position.textIconV': {
14310: $opt['mk']['tp'] = 3;
14311: break;
14312: }
14313: case 4:
14314: case 'position.iconTextH': {
14315: $opt['mk']['tp'] = 4;
14316: break;
14317: }
14318: case 5:
14319: case 'position.textIconH': {
14320: $opt['mk']['tp'] = 5;
14321: break;
14322: }
14323: case 6:
14324: case 'position.overlay': {
14325: $opt['mk']['tp'] = 6;
14326: break;
14327: }
14328: }
14329: }
14330:
14331: if (isset($prop['fillColor'])) {
14332: if (is_array($prop['fillColor'])) {
14333: $opt['mk']['bg'] = $prop['fillColor'];
14334: } else {
14335: $opt['mk']['bg'] = $this->convertHTMLColorToDec($prop['fillColor']);
14336: }
14337: }
14338:
14339: if (isset($prop['strokeColor'])) {
14340: if (is_array($prop['strokeColor'])) {
14341: $opt['mk']['bc'] = $prop['strokeColor'];
14342: } else {
14343: $opt['mk']['bc'] = $this->convertHTMLColorToDec($prop['strokeColor']);
14344: }
14345: }
14346:
14347: if (isset($prop['rotation'])) {
14348: $opt['mk']['r'] = $prop['rotation'];
14349: }
14350:
14351: if (isset($prop['charLimit'])) {
14352: $opt['maxlen'] = intval($prop['charLimit']);
14353: }
14354: if (!isset($ff)) {
14355: $ff = 0;
14356: }
14357:
14358: if (isset($prop['readonly']) AND ($prop['readonly'] == 'true')) {
14359: $ff += 1 << 0;
14360: }
14361:
14362: if (isset($prop['required']) AND ($prop['required'] == 'true')) {
14363: $ff += 1 << 1;
14364: }
14365:
14366: if (isset($prop['multiline']) AND ($prop['multiline'] == 'true')) {
14367: $ff += 1 << 12;
14368: }
14369:
14370: if (isset($prop['password']) AND ($prop['password'] == 'true')) {
14371: $ff += 1 << 13;
14372: }
14373:
14374: if (isset($prop['NoToggleToOff']) AND ($prop['NoToggleToOff'] == 'true')) {
14375: $ff += 1 << 14;
14376: }
14377:
14378: if (isset($prop['Radio']) AND ($prop['Radio'] == 'true')) {
14379: $ff += 1 << 15;
14380: }
14381:
14382: if (isset($prop['Pushbutton']) AND ($prop['Pushbutton'] == 'true')) {
14383: $ff += 1 << 16;
14384: }
14385:
14386: if (isset($prop['Combo']) AND ($prop['Combo'] == 'true')) {
14387: $ff += 1 << 17;
14388: }
14389:
14390: if (isset($prop['editable']) AND ($prop['editable'] == 'true')) {
14391: $ff += 1 << 18;
14392: }
14393:
14394: if (isset($prop['Sort']) AND ($prop['Sort'] == 'true')) {
14395: $ff += 1 << 19;
14396: }
14397:
14398: if (isset($prop['fileSelect']) AND ($prop['fileSelect'] == 'true')) {
14399: $ff += 1 << 20;
14400: }
14401:
14402: if (isset($prop['multipleSelection']) AND ($prop['multipleSelection'] == 'true')) {
14403: $ff += 1 << 21;
14404: }
14405:
14406: if (isset($prop['doNotSpellCheck']) AND ($prop['doNotSpellCheck'] == 'true')) {
14407: $ff += 1 << 22;
14408: }
14409:
14410: if (isset($prop['doNotScroll']) AND ($prop['doNotScroll'] == 'true')) {
14411: $ff += 1 << 23;
14412: }
14413:
14414: if (isset($prop['comb']) AND ($prop['comb'] == 'true')) {
14415: $ff += 1 << 24;
14416: }
14417:
14418: if (isset($prop['radiosInUnison']) AND ($prop['radiosInUnison'] == 'true')) {
14419: $ff += 1 << 25;
14420: }
14421:
14422: if (isset($prop['richText']) AND ($prop['richText'] == 'true')) {
14423: $ff += 1 << 25;
14424: }
14425:
14426: if (isset($prop['commitOnSelChange']) AND ($prop['commitOnSelChange'] == 'true')) {
14427: $ff += 1 << 26;
14428: }
14429: $opt['ff'] = $ff;
14430:
14431: if (isset($prop['defaultValue'])) {
14432: $opt['dv'] = $prop['defaultValue'];
14433: }
14434: $f = 4;
14435:
14436: if (isset($prop['readonly']) AND ($prop['readonly'] == 'true')) {
14437: $f += 1 << 6;
14438: }
14439:
14440: if (isset($prop['display'])) {
14441: if ($prop['display'] == 'display.visible') {
14442:
14443: } elseif ($prop['display'] == 'display.hidden') {
14444: $f += 1 << 1;
14445: } elseif ($prop['display'] == 'display.noPrint') {
14446: $f -= 1 << 2;
14447: } elseif ($prop['display'] == 'display.noView') {
14448: $f += 1 << 5;
14449: }
14450: }
14451: $opt['f'] = $f;
14452:
14453: if (isset($prop['currentValueIndices']) AND is_array($prop['currentValueIndices'])) {
14454: $opt['i'] = $prop['currentValueIndices'];
14455: }
14456:
14457: if (isset($prop['value'])) {
14458: if (is_array($prop['value'])) {
14459: $opt['opt'] = array();
14460: foreach ($prop['value'] AS $key => $optval) {
14461:
14462: if (isset($prop['exportValues'][$key])) {
14463: $opt['opt'][$key] = array($prop['exportValues'][$key], $prop['value'][$key]);
14464: } else {
14465: $opt['opt'][$key] = $prop['value'][$key];
14466: }
14467: }
14468: } else {
14469: $opt['v'] = $prop['value'];
14470: }
14471: }
14472:
14473: if (isset($prop['richValue'])) {
14474: $opt['rv'] = $prop['richValue'];
14475: }
14476:
14477: if (isset($prop['submitName'])) {
14478: $opt['tm'] = $prop['submitName'];
14479: }
14480:
14481: if (isset($prop['name'])) {
14482: $opt['t'] = $prop['name'];
14483: }
14484:
14485: if (isset($prop['userName'])) {
14486: $opt['tu'] = $prop['userName'];
14487: }
14488:
14489: if (isset($prop['highlight'])) {
14490: switch ($prop['highlight']) {
14491: case 'none':
14492: case 'highlight.n': {
14493: $opt['h'] = 'N';
14494: break;
14495: }
14496: case 'invert':
14497: case 'highlight.i': {
14498: $opt['h'] = 'i';
14499: break;
14500: }
14501: case 'push':
14502: case 'highlight.p': {
14503: $opt['h'] = 'P';
14504: break;
14505: }
14506: case 'outline':
14507: case 'highlight.o': {
14508: $opt['h'] = 'O';
14509: break;
14510: }
14511: }
14512: }
14513:
14514:
14515:
14516:
14517:
14518:
14519: return $opt;
14520: }
14521:
14522: 14523: 14524: 14525: 14526: 14527: 14528:
14529: public function setFormDefaultProp($prop=array()) {
14530: $this->default_form_prop = $prop;
14531: }
14532:
14533: 14534: 14535: 14536: 14537: 14538: 14539:
14540: public function getFormDefaultProp() {
14541: return $this->default_form_prop;
14542: }
14543:
14544: 14545: 14546: 14547: 14548: 14549: 14550: 14551: 14552: 14553: 14554: 14555: 14556: 14557:
14558: public function TextField($name, $w, $h, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
14559: if ($x === '') {
14560: $x = $this->x;
14561: }
14562: if ($y === '') {
14563: $y = $this->y;
14564: }
14565:
14566: $this->checkPageRegions($h, $x, $y);
14567: if ($js) {
14568: $this->_addfield('text', $name, $x, $y, $w, $h, $prop);
14569: return;
14570: }
14571:
14572: $prop = array_merge($this->getFormDefaultProp(), $prop);
14573:
14574: $popt = $this->getAnnotOptFromJSProp($prop);
14575:
14576: $this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i'];
14577: $fontstyle = sprintf('/F%d %.2F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor);
14578: $popt['da'] = $fontstyle;
14579: $popt['ap'] = array();
14580: $popt['ap']['n'] = 'q BT '.$fontstyle.' ET Q';
14581:
14582: $opt = array_merge($popt, $opt);
14583:
14584: unset($opt['bs']);
14585:
14586: $opt['Subtype'] = 'Widget';
14587: $opt['ft'] = 'Tx';
14588: $opt['t'] = $name;
14589: 14590: 14591: 14592: 14593: 14594: 14595: 14596: 14597: 14598: 14599: 14600: 14601: 14602: 14603: 14604: 14605: 14606: 14607: 14608: 14609: 14610: 14611: 14612: 14613: 14614: 14615: 14616: 14617: 14618: 14619: 14620: 14621: 14622: 14623:
14624: $this->Annotation($x, $y, $w, $h, $name, $opt, 0);
14625: if ($this->rtl) {
14626: $this->x -= $w;
14627: } else {
14628: $this->x += $w;
14629: }
14630: }
14631:
14632: 14633: 14634: 14635: 14636: 14637: 14638: 14639: 14640: 14641: 14642: 14643: 14644: 14645: 14646:
14647: public function RadioButton($name, $w, $prop=array(), $opt=array(), $onvalue='On', $checked=false, $x='', $y='', $js=false) {
14648: if ($x === '') {
14649: $x = $this->x;
14650: }
14651: if ($y === '') {
14652: $y = $this->y;
14653: }
14654:
14655: $this->checkPageRegions($w, $x, $y);
14656: if ($js) {
14657: $this->_addfield('radiobutton', $name, $x, $y, $w, $w, $prop);
14658: return;
14659: }
14660: if ($this->empty_string($onvalue)) {
14661: $onvalue = 'On';
14662: }
14663: if ($checked) {
14664: $defval = $onvalue;
14665: } else {
14666: $defval = 'Off';
14667: }
14668:
14669: if (!isset($this->radiobutton_groups[$this->page])) {
14670: $this->radiobutton_groups[$this->page] = array();
14671: }
14672: if (!isset($this->radiobutton_groups[$this->page][$name])) {
14673: $this->radiobutton_groups[$this->page][$name] = array();
14674: ++$this->n;
14675: $this->radiobutton_groups[$this->page][$name]['n'] = $this->n;
14676: $this->radio_groups[] = $this->n;
14677: $kid = ($this->n + 2);
14678: } else {
14679: $kid = ($this->n + 1);
14680: }
14681:
14682: $this->radiobutton_groups[$this->page][$name][] = array('kid' => $kid, 'def' => $defval);
14683:
14684: $prop = array_merge($this->getFormDefaultProp(), $prop);
14685: $prop['NoToggleToOff'] = 'true';
14686: $prop['Radio'] = 'true';
14687: $prop['borderStyle'] = 'inset';
14688:
14689: $popt = $this->getAnnotOptFromJSProp($prop);
14690:
14691: $font = 'zapfdingbats';
14692: $this->AddFont($font);
14693: $tmpfont = $this->getFontBuffer($font);
14694: $this->annotation_fonts[$tmpfont['fontkey']] = $tmpfont['i'];
14695: $fontstyle = sprintf('/F%d %.2F Tf %s', $tmpfont['i'], $this->FontSizePt, $this->TextColor);
14696: $popt['da'] = $fontstyle;
14697: $popt['ap'] = array();
14698: $popt['ap']['n'] = array();
14699: $popt['ap']['n'][$onvalue] = 'q BT '.$fontstyle.' 0 0 Td (8) Tj ET Q';
14700: $popt['ap']['n']['Off'] = 'q BT '.$fontstyle.' 0 0 Td (8) Tj ET Q';
14701: if (!isset($popt['mk'])) {
14702: $popt['mk'] = array();
14703: }
14704: $popt['mk']['ca'] = '(l)';
14705:
14706: $opt = array_merge($popt, $opt);
14707:
14708: $opt['Subtype'] = 'Widget';
14709: $opt['ft'] = 'Btn';
14710: if ($checked) {
14711: $opt['v'] = array('/'.$onvalue);
14712: $opt['as'] = $onvalue;
14713: } else {
14714: $opt['as'] = 'Off';
14715: }
14716: $this->Annotation($x, $y, $w, $w, $name, $opt, 0);
14717: if ($this->rtl) {
14718: $this->x -= $w;
14719: } else {
14720: $this->x += $w;
14721: }
14722: }
14723:
14724: 14725: 14726: 14727: 14728: 14729: 14730: 14731: 14732: 14733: 14734: 14735: 14736: 14737: 14738:
14739: public function ListBox($name, $w, $h, $values, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
14740: if ($x === '') {
14741: $x = $this->x;
14742: }
14743: if ($y === '') {
14744: $y = $this->y;
14745: }
14746:
14747: $this->checkPageRegions($h, $x, $y);
14748: if ($js) {
14749: $this->_addfield('listbox', $name, $x, $y, $w, $h, $prop);
14750: $s = '';
14751: foreach ($values as $value) {
14752: $s .= "'".addslashes($value)."',";
14753: }
14754: $this->javascript .= 'f'.$name.'.setItems(['.substr($s, 0, -1)."]);\n";
14755: return;
14756: }
14757:
14758: $prop = array_merge($this->getFormDefaultProp(), $prop);
14759:
14760: $popt = $this->getAnnotOptFromJSProp($prop);
14761:
14762: $this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i'];
14763: $fontstyle = sprintf('/F%d %.2F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor);
14764: $popt['da'] = $fontstyle;
14765: $popt['ap'] = array();
14766: $popt['ap']['n'] = 'q BT '.$fontstyle.' ET Q';
14767:
14768: $opt = array_merge($popt, $opt);
14769:
14770: $opt['Subtype'] = 'Widget';
14771: $opt['ft'] = 'Ch';
14772: $opt['t'] = $name;
14773: $opt['opt'] = $values;
14774: $this->Annotation($x, $y, $w, $h, $name, $opt, 0);
14775: if ($this->rtl) {
14776: $this->x -= $w;
14777: } else {
14778: $this->x += $w;
14779: }
14780: }
14781:
14782: 14783: 14784: 14785: 14786: 14787: 14788: 14789: 14790: 14791: 14792: 14793: 14794: 14795: 14796:
14797: public function ComboBox($name, $w, $h, $values, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
14798: if ($x === '') {
14799: $x = $this->x;
14800: }
14801: if ($y === '') {
14802: $y = $this->y;
14803: }
14804:
14805: $this->checkPageRegions($h, $x, $y);
14806: if ($js) {
14807: $this->_addfield('combobox', $name, $x, $y, $w, $h, $prop);
14808: $s = '';
14809: foreach ($values as $value) {
14810: $s .= "'".addslashes($value)."',";
14811: }
14812: $this->javascript .= 'f'.$name.'.setItems(['.substr($s, 0, -1)."]);\n";
14813: return;
14814: }
14815:
14816: $prop = array_merge($this->getFormDefaultProp(), $prop);
14817: $prop['Combo'] = true;
14818:
14819: $popt = $this->getAnnotOptFromJSProp($prop);
14820:
14821: $this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i'];
14822: $fontstyle = sprintf('/F%d %.2F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor);
14823: $popt['da'] = $fontstyle;
14824: $popt['ap'] = array();
14825: $popt['ap']['n'] = 'q BT '.$fontstyle.' ET Q';
14826:
14827: $opt = array_merge($popt, $opt);
14828:
14829: $opt['Subtype'] = 'Widget';
14830: $opt['ft'] = 'Ch';
14831: $opt['t'] = $name;
14832: $opt['opt'] = $values;
14833: $this->Annotation($x, $y, $w, $h, $name, $opt, 0);
14834: if ($this->rtl) {
14835: $this->x -= $w;
14836: } else {
14837: $this->x += $w;
14838: }
14839: }
14840:
14841: 14842: 14843: 14844: 14845: 14846: 14847: 14848: 14849: 14850: 14851: 14852: 14853: 14854: 14855:
14856: public function CheckBox($name, $w, $checked=false, $prop=array(), $opt=array(), $onvalue='Yes', $x='', $y='', $js=false) {
14857: if ($x === '') {
14858: $x = $this->x;
14859: }
14860: if ($y === '') {
14861: $y = $this->y;
14862: }
14863:
14864: $this->checkPageRegions($w, $x, $y);
14865: if ($js) {
14866: $this->_addfield('checkbox', $name, $x, $y, $w, $w, $prop);
14867: return;
14868: }
14869: if (!isset($prop['value'])) {
14870: $prop['value'] = array('Yes');
14871: }
14872:
14873: $prop = array_merge($this->getFormDefaultProp(), $prop);
14874: $prop['borderStyle'] = 'inset';
14875:
14876: $popt = $this->getAnnotOptFromJSProp($prop);
14877:
14878: $font = 'zapfdingbats';
14879: $this->AddFont($font);
14880: $tmpfont = $this->getFontBuffer($font);
14881: $this->annotation_fonts[$tmpfont['fontkey']] = $tmpfont['i'];
14882: $fontstyle = sprintf('/F%d %.2F Tf %s', $tmpfont['i'], $this->FontSizePt, $this->TextColor);
14883: $popt['da'] = $fontstyle;
14884: $popt['ap'] = array();
14885: $popt['ap']['n'] = array();
14886: $popt['ap']['n']['Yes'] = 'q BT '.$fontstyle.' 0 0 Td (8) Tj ET Q';
14887: $popt['ap']['n']['Off'] = 'q BT '.$fontstyle.' 0 0 Td (8) Tj ET Q';
14888:
14889: $opt = array_merge($popt, $opt);
14890:
14891: $opt['Subtype'] = 'Widget';
14892: $opt['ft'] = 'Btn';
14893: $opt['t'] = $name;
14894: $opt['opt'] = array($onvalue);
14895: if ($checked) {
14896: $opt['v'] = array('/0');
14897: $opt['as'] = 'Yes';
14898: } else {
14899: $opt['v'] = array('/Off');
14900: $opt['as'] = 'Off';
14901: }
14902: $this->Annotation($x, $y, $w, $w, $name, $opt, 0);
14903: if ($this->rtl) {
14904: $this->x -= $w;
14905: } else {
14906: $this->x += $w;
14907: }
14908: }
14909:
14910: 14911: 14912: 14913: 14914: 14915: 14916: 14917: 14918: 14919: 14920: 14921: 14922: 14923: 14924: 14925:
14926: public function Button($name, $w, $h, $caption, $action, $prop=array(), $opt=array(), $x='', $y='', $js=false) {
14927: if ($x === '') {
14928: $x = $this->x;
14929: }
14930: if ($y === '') {
14931: $y = $this->y;
14932: }
14933:
14934: $this->checkPageRegions($h, $x, $y);
14935: if ($js) {
14936: $this->_addfield('button', $name, $this->x, $this->y, $w, $h, $prop);
14937: $this->javascript .= 'f'.$name.".buttonSetCaption('".addslashes($caption)."');\n";
14938: $this->javascript .= 'f'.$name.".setAction('MouseUp','".addslashes($action)."');\n";
14939: $this->javascript .= 'f'.$name.".highlight='push';\n";
14940: $this->javascript .= 'f'.$name.".print=false;\n";
14941: return;
14942: }
14943:
14944: $prop = array_merge($this->getFormDefaultProp(), $prop);
14945: $prop['Pushbutton'] = 'true';
14946: $prop['highlight'] = 'push';
14947: $prop['display'] = 'display.noPrint';
14948:
14949: $popt = $this->getAnnotOptFromJSProp($prop);
14950: $this->annotation_fonts[$this->CurrentFont['fontkey']] = $this->CurrentFont['i'];
14951: $fontstyle = sprintf('/F%d %.2F Tf %s', $this->CurrentFont['i'], $this->FontSizePt, $this->TextColor);
14952: $popt['da'] = $fontstyle;
14953: $popt['ap'] = array();
14954: $popt['ap']['n'] = 'q BT '.$fontstyle.' ET Q';
14955:
14956: if (!isset($popt['mk'])) {
14957: $popt['mk'] = array();
14958: }
14959: $ann_obj_id = ($this->n + 1);
14960: if (!empty($action) AND !is_array($action)) {
14961: $ann_obj_id = ($this->n + 2);
14962: }
14963: $popt['mk']['ca'] = $this->_textstring($caption, $ann_obj_id);
14964: $popt['mk']['rc'] = $this->_textstring($caption, $ann_obj_id);
14965: $popt['mk']['ac'] = $this->_textstring($caption, $ann_obj_id);
14966:
14967: $opt = array_merge($popt, $opt);
14968:
14969: $opt['Subtype'] = 'Widget';
14970: $opt['ft'] = 'Btn';
14971: $opt['t'] = $caption;
14972: $opt['v'] = $name;
14973: if (!empty($action)) {
14974: if (is_array($action)) {
14975:
14976: $opt['aa'] = '/D <<';
14977: $bmode = array('SubmitForm', 'ResetForm', 'ImportData');
14978: foreach ($action AS $key => $val) {
14979: if (($key == 'S') AND in_array($val, $bmode)) {
14980: $opt['aa'] .= ' /S /'.$val;
14981: } elseif (($key == 'F') AND (!empty($val))) {
14982: $opt['aa'] .= ' /F '.$this->_datastring($val, $ann_obj_id);
14983: } elseif (($key == 'Fields') AND is_array($val) AND !empty($val)) {
14984: $opt['aa'] .= ' /Fields [';
14985: foreach ($val AS $field) {
14986: $opt['aa'] .= ' '.$this->_textstring($field, $ann_obj_id);
14987: }
14988: $opt['aa'] .= ']';
14989: } elseif (($key == 'Flags')) {
14990: $ff = 0;
14991: if (is_array($val)) {
14992: foreach ($val AS $flag) {
14993: switch ($flag) {
14994: case 'Include/Exclude': {
14995: $ff += 1 << 0;
14996: break;
14997: }
14998: case 'IncludeNoValueFields': {
14999: $ff += 1 << 1;
15000: break;
15001: }
15002: case 'ExportFormat': {
15003: $ff += 1 << 2;
15004: break;
15005: }
15006: case 'GetMethod': {
15007: $ff += 1 << 3;
15008: break;
15009: }
15010: case 'SubmitCoordinates': {
15011: $ff += 1 << 4;
15012: break;
15013: }
15014: case 'XFDF': {
15015: $ff += 1 << 5;
15016: break;
15017: }
15018: case 'IncludeAppendSaves': {
15019: $ff += 1 << 6;
15020: break;
15021: }
15022: case 'IncludeAnnotations': {
15023: $ff += 1 << 7;
15024: break;
15025: }
15026: case 'SubmitPDF': {
15027: $ff += 1 << 8;
15028: break;
15029: }
15030: case 'CanonicalFormat': {
15031: $ff += 1 << 9;
15032: break;
15033: }
15034: case 'ExclNonUserAnnots': {
15035: $ff += 1 << 10;
15036: break;
15037: }
15038: case 'ExclFKey': {
15039: $ff += 1 << 11;
15040: break;
15041: }
15042: case 'EmbedForm': {
15043: $ff += 1 << 13;
15044: break;
15045: }
15046: }
15047: }
15048: } else {
15049: $ff = intval($val);
15050: }
15051: $opt['aa'] .= ' /Flags '.$ff;
15052: }
15053: }
15054: $opt['aa'] .= ' >>';
15055: } else {
15056:
15057: $js_obj_id = $this->addJavascriptObject($action);
15058: $opt['aa'] = '/D '.$js_obj_id.' 0 R';
15059: }
15060: }
15061: $this->Annotation($x, $y, $w, $h, $name, $opt, 0);
15062: if ($this->rtl) {
15063: $this->x -= $w;
15064: } else {
15065: $this->x += $w;
15066: }
15067: }
15068:
15069:
15070:
15071: 15072: 15073: 15074: 15075: 15076: 15077:
15078: protected function _putsignature() {
15079: if ((!$this->sign) OR (!isset($this->signature_data['cert_type']))) {
15080: return;
15081: }
15082: $out = $this->_getobj($this->sig_obj_id + 1)."\n";
15083: $out .= '<< /Type /Sig';
15084: $out .= ' /Filter /Adobe.PPKLite';
15085: $out .= ' /SubFilter /adbe.pkcs7.detached';
15086: $out .= ' '.$this->byterange_string;
15087: $out .= ' /Contents<'.str_repeat('0', $this->signature_max_length).'>';
15088: $out .= ' /Reference [';
15089: $out .= ' << /Type /SigRef';
15090: if ($this->signature_data['cert_type'] > 0) {
15091: $out .= ' /TransformMethod /DocMDP';
15092: $out .= ' /TransformParams <<';
15093: $out .= ' /Type /TransformParams';
15094: $out .= ' /V /1.2';
15095: $out .= ' /P '.$this->signature_data['cert_type'];
15096: } else {
15097: $out .= ' /TransformMethod /UR3';
15098: $out .= ' /TransformParams <<';
15099: $out .= ' /Type /TransformParams';
15100: $out .= ' /V /2.2';
15101: if (!$this->empty_string($this->ur['document'])) {
15102: $out .= ' /Document['.$this->ur['document'].']';
15103: }
15104: if (!$this->empty_string($this->ur['form'])) {
15105: $out .= ' /Form['.$this->ur['form'].']';
15106: }
15107: if (!$this->empty_string($this->ur['signature'])) {
15108: $out .= ' /Signature['.$this->ur['signature'].']';
15109: }
15110: if (!$this->empty_string($this->ur['annots'])) {
15111: $out .= ' /Annots['.$this->ur['annots'].']';
15112: }
15113: if (!$this->empty_string($this->ur['ef'])) {
15114: $out .= ' /EF['.$this->ur['ef'].']';
15115: }
15116: if (!$this->empty_string($this->ur['formex'])) {
15117: $out .= ' /FormEX['.$this->ur['formex'].']';
15118: }
15119: }
15120: $out .= ' >>';
15121:
15122:
15123:
15124:
15125:
15126: $out .= ' >>';
15127: $out .= ' ]';
15128: if (isset($this->signature_data['info']['Name']) AND !$this->empty_string($this->signature_data['info']['Name'])) {
15129: $out .= ' /Name '.$this->_textstring($this->signature_data['info']['Name']);
15130: }
15131: if (isset($this->signature_data['info']['Location']) AND !$this->empty_string($this->signature_data['info']['Location'])) {
15132: $out .= ' /Location '.$this->_textstring($this->signature_data['info']['Location']);
15133: }
15134: if (isset($this->signature_data['info']['Reason']) AND !$this->empty_string($this->signature_data['info']['Reason'])) {
15135: $out .= ' /Reason '.$this->_textstring($this->signature_data['info']['Reason']);
15136: }
15137: if (isset($this->signature_data['info']['ContactInfo']) AND !$this->empty_string($this->signature_data['info']['ContactInfo'])) {
15138: $out .= ' /ContactInfo '.$this->_textstring($this->signature_data['info']['ContactInfo']);
15139: }
15140: $out .= ' /M '.$this->_datestring();
15141: $out .= ' >>';
15142: $out .= "\n".'endobj';
15143: $this->_out($out);
15144: }
15145:
15146: 15147: 15148: 15149: 15150: 15151: 15152: 15153: 15154: 15155: 15156: 15157: 15158: 15159: 15160: 15161: 15162:
15163: public function setUserRights(
15164: $enable=true,
15165: $document='/FullSave',
15166: $annots='/Create/Delete/Modify/Copy/Import/Export',
15167: $form='/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate',
15168: $signature='/Modify',
15169: $ef='/Create/Delete/Modify/Import',
15170: $formex='') {
15171: $this->ur['enabled'] = $enable;
15172: $this->ur['document'] = $document;
15173: $this->ur['annots'] = $annots;
15174: $this->ur['form'] = $form;
15175: $this->ur['signature'] = $signature;
15176: $this->ur['ef'] = $ef;
15177: $this->ur['formex'] = $formex;
15178: if (!$this->sign) {
15179: $this->setSignature('', '', '', '', 0, array());
15180: }
15181: }
15182:
15183: 15184: 15185: 15186: 15187: 15188: 15189: 15190: 15191: 15192: 15193: 15194: 15195: 15196: 15197: 15198:
15199: public function setSignature($signing_cert='', $private_key='', $private_key_password='', $extracerts='', $cert_type=2, $info=array()) {
15200:
15201:
15202:
15203:
15204: $this->sign = true;
15205: ++$this->n;
15206: $this->sig_obj_id = $this->n;
15207: ++$this->n;
15208: $this->signature_data = array();
15209: if (strlen($signing_cert) == 0) {
15210: $signing_cert = 'file://'.dirname(__FILE__).'/tcpdf.crt';
15211: $private_key_password = 'tcpdfdemo';
15212: }
15213: if (strlen($private_key) == 0) {
15214: $private_key = $signing_cert;
15215: }
15216: $this->signature_data['signcert'] = $signing_cert;
15217: $this->signature_data['privkey'] = $private_key;
15218: $this->signature_data['password'] = $private_key_password;
15219: $this->signature_data['extracerts'] = $extracerts;
15220: $this->signature_data['cert_type'] = $cert_type;
15221: $this->signature_data['info'] = $info;
15222: }
15223:
15224: 15225: 15226: 15227: 15228: 15229: 15230: 15231: 15232: 15233: 15234:
15235: public function setSignatureAppearance($x=0, $y=0, $w=0, $h=0, $page=-1) {
15236: if (($page < 1) OR ($page > $this->numpages)) {
15237: $this->signature_appearance['page'] = $this->page;
15238: } else {
15239: $this->signature_appearance['page'] = intval($page);
15240: }
15241: $a = $x * $this->k;
15242: $b = $this->pagedim[($this->signature_appearance['page'])]['h'] - (($y + $h) * $this->k);
15243: $c = $w * $this->k;
15244: $d = $h * $this->k;
15245: $this->signature_appearance['rect'] = sprintf('%.2F %.2F %.2F %.2F', $a, $b, $a+$c, $b+$d);
15246: }
15247:
15248: 15249: 15250: 15251: 15252: 15253: 15254:
15255: public function startPageGroup($page='') {
15256: if (empty($page)) {
15257: $page = $this->page + 1;
15258: }
15259: $this->newpagegroup[$page] = true;
15260: }
15261:
15262: 15263: 15264: 15265: 15266: 15267: 15268: 15269:
15270: public function AliasNbPages($alias='{nb}') {
15271: $this->AliasNbPages = $alias;
15272: }
15273:
15274: 15275: 15276: 15277: 15278: 15279: 15280: 15281:
15282: public function getAliasNbPages() {
15283: if ($this->isUnicodeFont()) {
15284: return '{'.$this->AliasNbPages.'}';
15285: }
15286: return $this->AliasNbPages;
15287: }
15288:
15289: 15290: 15291: 15292: 15293: 15294: 15295: 15296:
15297: public function AliasNumPage($alias='{pnb}') {
15298:
15299: $this->AliasNumPage = $alias;
15300: }
15301:
15302: 15303: 15304: 15305: 15306: 15307: 15308: 15309:
15310: public function getAliasNumPage() {
15311: if ($this->isUnicodeFont()) {
15312: return '{'.$this->AliasNumPage.'}';
15313: }
15314: return $this->AliasNumPage;
15315: }
15316:
15317: 15318: 15319: 15320: 15321: 15322:
15323: public function getGroupPageNo() {
15324: return $this->pagegroups[$this->currpagegroup];
15325: }
15326:
15327: 15328: 15329: 15330: 15331: 15332:
15333: public function getGroupPageNoFormatted() {
15334: return $this->formatPageNumber($this->getGroupPageNo());
15335: }
15336:
15337: 15338: 15339: 15340: 15341: 15342: 15343: 15344:
15345: public function getPageGroupAlias() {
15346: if ($this->isUnicodeFont()) {
15347: return '{'.$this->currpagegroup.'}';
15348: }
15349: return $this->currpagegroup;
15350: }
15351:
15352: 15353: 15354: 15355: 15356: 15357: 15358: 15359:
15360: public function getPageNumGroupAlias() {
15361: if ($this->isUnicodeFont()) {
15362: return '{'.str_replace('{nb', '{pnb', $this->currpagegroup).'}';
15363: }
15364: return str_replace('{nb', '{pnb', $this->currpagegroup);
15365: }
15366:
15367: 15368: 15369: 15370: 15371: 15372: 15373:
15374: protected function formatPageNumber($num) {
15375: return number_format((float)$num, 0, '', '.');
15376: }
15377:
15378: 15379: 15380: 15381: 15382: 15383: 15384: 15385:
15386: protected function formatTOCPageNumber($num) {
15387: return number_format((float)$num, 0, '', '.');
15388: }
15389:
15390: 15391: 15392: 15393: 15394: 15395:
15396: public function PageNoFormatted() {
15397: return $this->formatPageNumber($this->PageNo());
15398: }
15399:
15400: 15401: 15402: 15403: 15404:
15405: protected function _putocg() {
15406: $this->n_ocg_print = $this->_newobj();
15407: $this->_out('<< /Type /OCG /Name '.$this->_textstring('print', $this->n_ocg_print).' /Usage << /Print <</PrintState /ON>> /View <</ViewState /OFF>> >> >>'."\n".'endobj');
15408: $this->n_ocg_view = $this->_newobj();
15409: $this->_out('<< /Type /OCG /Name '.$this->_textstring('view', $this->n_ocg_view).' /Usage << /Print <</PrintState /OFF>> /View <</ViewState /ON>> >> >>'."\n".'endobj');
15410: }
15411:
15412: 15413: 15414: 15415: 15416: 15417: 15418: 15419:
15420: public function setVisibility($v) {
15421: if ($this->openMarkedContent) {
15422:
15423: $this->_out('EMC');
15424: $this->openMarkedContent = false;
15425: }
15426: switch($v) {
15427: case 'print': {
15428: $this->_out('/OC /OC1 BDC');
15429: $this->openMarkedContent = true;
15430: break;
15431: }
15432: case 'screen': {
15433: $this->_out('/OC /OC2 BDC');
15434: $this->openMarkedContent = true;
15435: break;
15436: }
15437: case 'all': {
15438: $this->_out('');
15439: break;
15440: }
15441: default: {
15442: $this->Error('Incorrect visibility: '.$v);
15443: break;
15444: }
15445: }
15446: $this->visibility = $v;
15447: }
15448:
15449: 15450: 15451: 15452: 15453: 15454: 15455:
15456: protected function addExtGState($parms) {
15457: $n = count($this->extgstates) + 1;
15458:
15459: for ($i = 1; $i < $n; ++$i) {
15460: if ($this->extgstates[$i]['parms'] == $parms) {
15461:
15462: return $i;
15463: }
15464: }
15465: $this->extgstates[$n]['parms'] = $parms;
15466: return $n;
15467: }
15468:
15469: 15470: 15471: 15472: 15473: 15474:
15475: protected function setExtGState($gs) {
15476: $this->_out(sprintf('/GS%d gs', $gs));
15477: }
15478:
15479: 15480: 15481: 15482: 15483: 15484:
15485: protected function _putextgstates() {
15486: $ne = count($this->extgstates);
15487: for ($i = 1; $i <= $ne; ++$i) {
15488: $this->extgstates[$i]['n'] = $this->_newobj();
15489: $out = '<< /Type /ExtGState';
15490: foreach ($this->extgstates[$i]['parms'] as $k => $v) {
15491: if (is_float($v)) {
15492: $v = sprintf('%.2F', $v);
15493: }
15494: $out .= ' /'.$k.' '.$v;
15495: }
15496: $out .= ' >>';
15497: $out .= "\n".'endobj';
15498: $this->_out($out);
15499: }
15500: }
15501:
15502: 15503: 15504: 15505: 15506: 15507: 15508:
15509: public function setAlpha($alpha, $bm='Normal') {
15510: $gs = $this->addExtGState(array('ca' => $alpha, 'CA' => $alpha, 'BM' => '/'.$bm, 'AIS' => 'false'));
15511: $this->setExtGState($gs);
15512: }
15513:
15514: 15515: 15516: 15517: 15518: 15519:
15520: public function setJPEGQuality($quality) {
15521: if (($quality < 1) OR ($quality > 100)) {
15522: $quality = 75;
15523: }
15524: $this->jpeg_quality = intval($quality);
15525: }
15526:
15527: 15528: 15529: 15530: 15531: 15532:
15533: public function setDefaultTableColumns($cols=4) {
15534: $this->default_table_columns = intval($cols);
15535: }
15536:
15537: 15538: 15539: 15540: 15541: 15542:
15543: public function setCellHeightRatio($h) {
15544: $this->cell_height_ratio = $h;
15545: }
15546:
15547: 15548: 15549: 15550: 15551:
15552: public function getCellHeightRatio() {
15553: return $this->cell_height_ratio;
15554: }
15555:
15556: 15557: 15558: 15559: 15560: 15561:
15562: public function setPDFVersion($version='1.7') {
15563: $this->PDFVersion = $version;
15564: }
15565:
15566: 15567: 15568: 15569: 15570: 15571: 15572: 15573: 15574:
15575: public function setViewerPreferences($preferences) {
15576: $this->viewer_preferences = $preferences;
15577: }
15578:
15579: 15580: 15581: 15582: 15583: 15584: 15585: 15586: 15587: 15588: 15589: 15590: 15591:
15592: public function colorRegistrationBar($x, $y, $w, $h, $transition=true, $vertical=false, $colors='A,R,G,B,C,M,Y,K') {
15593: $bars = explode(',', $colors);
15594: $numbars = count($bars);
15595:
15596: if ($vertical) {
15597: $coords = array(0, 0, 0, 1);
15598: $wb = $w / $numbars;
15599: $hb = $h;
15600: $xd = $wb;
15601: $yd = 0;
15602: } else {
15603: $coords = array(1, 0, 0, 0);
15604: $wb = $w;
15605: $hb = $h / $numbars;
15606: $xd = 0;
15607: $yd = $hb;
15608: }
15609: $xb = $x;
15610: $yb = $y;
15611: foreach ($bars as $col) {
15612: switch ($col) {
15613:
15614: case 'A': {
15615: $col_a = array(255);
15616: $col_b = array(0);
15617: break;
15618: }
15619: case 'W': {
15620: $col_a = array(0);
15621: $col_b = array(255);
15622: break;
15623: }
15624: case 'R': {
15625: $col_a = array(255,255,255);
15626: $col_b = array(255,0,0);
15627: break;
15628: }
15629: case 'G': {
15630: $col_a = array(255,255,255);
15631: $col_b = array(0,255,0);
15632: break;
15633: }
15634: case 'B': {
15635: $col_a = array(255,255,255);
15636: $col_b = array(0,0,255);
15637: break;
15638: }
15639: case 'C': {
15640: $col_a = array(0,0,0,0);
15641: $col_b = array(100,0,0,0);
15642: break;
15643: }
15644: case 'M': {
15645: $col_a = array(0,0,0,0);
15646: $col_b = array(0,100,0,0);
15647: break;
15648: }
15649: case 'Y': {
15650: $col_a = array(0,0,0,0);
15651: $col_b = array(0,0,100,0);
15652: break;
15653: }
15654: case 'K': {
15655: $col_a = array(0,0,0,0);
15656: $col_b = array(0,0,0,100);
15657: break;
15658: }
15659: default: {
15660: $col_a = array(255);
15661: $col_b = array(0);
15662: break;
15663: }
15664: }
15665: if ($transition) {
15666:
15667: $this->LinearGradient($xb, $yb, $wb, $hb, $col_a, $col_b, $coords);
15668: } else {
15669:
15670: $this->SetFillColorArray($col_b);
15671: $this->Rect($xb, $yb, $wb, $hb, 'F', array());
15672: }
15673: $xb += $xd;
15674: $yb += $yd;
15675: }
15676: }
15677:
15678: 15679: 15680: 15681: 15682: 15683: 15684: 15685: 15686: 15687: 15688: 15689:
15690: public function cropMark($x, $y, $w, $h, $type='A,B,C,D', $color=array(0,0,0)) {
15691: $this->SetLineStyle(array('width' => (0.5 / $this->k), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $color));
15692: $crops = explode(',', $type);
15693: $numcrops = count($crops);
15694: $dw = $w / 4;
15695: $dh = $h / 4;
15696: foreach ($crops as $crop) {
15697: switch ($crop) {
15698: case 'A': {
15699: $x1 = $x;
15700: $y1 = $y - $h;
15701: $x2 = $x;
15702: $y2 = $y - $dh;
15703: $x3 = $x - $w;
15704: $y3 = $y;
15705: $x4 = $x - $dw;
15706: $y4 = $y;
15707: break;
15708: }
15709: case 'B': {
15710: $x1 = $x;
15711: $y1 = $y - $h;
15712: $x2 = $x;
15713: $y2 = $y - $dh;
15714: $x3 = $x + $dw;
15715: $y3 = $y;
15716: $x4 = $x + $w;
15717: $y4 = $y;
15718: break;
15719: }
15720: case 'C': {
15721: $x1 = $x - $w;
15722: $y1 = $y;
15723: $x2 = $x - $dw;
15724: $y2 = $y;
15725: $x3 = $x;
15726: $y3 = $y + $dh;
15727: $x4 = $x;
15728: $y4 = $y + $h;
15729: break;
15730: }
15731: case 'D': {
15732: $x1 = $x + $dw;
15733: $y1 = $y;
15734: $x2 = $x + $w;
15735: $y2 = $y;
15736: $x3 = $x;
15737: $y3 = $y + $dh;
15738: $x4 = $x;
15739: $y4 = $y + $h;
15740: break;
15741: }
15742: }
15743: $this->Line($x1, $y1, $x2, $y2);
15744: $this->Line($x3, $y3, $x4, $y4);
15745: }
15746: }
15747:
15748: 15749: 15750: 15751: 15752: 15753: 15754: 15755: 15756: 15757: 15758: 15759:
15760: public function registrationMark($x, $y, $r, $double=false, $cola=array(0,0,0), $colb=array(255,255,255)) {
15761: $line_style = array('width' => (0.5 / $this->k), 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => $cola);
15762: $this->SetFillColorArray($cola);
15763: $this->PieSector($x, $y, $r, 90, 180, 'F');
15764: $this->PieSector($x, $y, $r, 270, 360, 'F');
15765: $this->Circle($x, $y, $r, 0, 360, 'C', $line_style, array(), 8);
15766: if ($double) {
15767: $r2 = $r * 0.5;
15768: $this->SetFillColorArray($colb);
15769: $this->PieSector($x, $y, $r2, 90, 180, 'F');
15770: $this->PieSector($x, $y, $r2, 270, 360, 'F');
15771: $this->SetFillColorArray($cola);
15772: $this->PieSector($x, $y, $r2, 0, 90, 'F');
15773: $this->PieSector($x, $y, $r2, 180, 270, 'F');
15774: $this->Circle($x, $y, $r2, 0, 360, 'C', $line_style, array(), 8);
15775: }
15776: }
15777:
15778: 15779: 15780: 15781: 15782: 15783: 15784: 15785: 15786: 15787: 15788: 15789: 15790:
15791: public function LinearGradient($x, $y, $w, $h, $col1=array(), $col2=array(), $coords=array(0,0,1,0)) {
15792: $this->Clip($x, $y, $w, $h);
15793: $this->Gradient(2, $coords, array(array('color' => $col1, 'offset' => 0, 'exponent' => 1), array('color' => $col2, 'offset' => 1, 'exponent' => 1)), array(), false);
15794: }
15795:
15796: 15797: 15798: 15799: 15800: 15801: 15802: 15803: 15804: 15805: 15806: 15807: 15808:
15809: public function RadialGradient($x, $y, $w, $h, $col1=array(), $col2=array(), $coords=array(0.5,0.5,0.5,0.5,1)) {
15810: $this->Clip($x, $y, $w, $h);
15811: $this->Gradient(3, $coords, array(array('color' => $col1, 'offset' => 0, 'exponent' => 1), array('color' => $col2, 'offset' => 1, 'exponent' => 1)), array(), false);
15812: }
15813:
15814: 15815: 15816: 15817: 15818: 15819: 15820: 15821: 15822: 15823: 15824: 15825: 15826: 15827: 15828: 15829: 15830: 15831:
15832: public function CoonsPatchMesh($x, $y, $w, $h, $col1=array(), $col2=array(), $col3=array(), $col4=array(), $coords=array(0.00,0.0,0.33,0.00,0.67,0.00,1.00,0.00,1.00,0.33,1.00,0.67,1.00,1.00,0.67,1.00,0.33,1.00,0.00,1.00,0.00,0.67,0.00,0.33), $coords_min=0, $coords_max=1, $antialias=false) {
15833: $this->Clip($x, $y, $w, $h);
15834: $n = count($this->gradients) + 1;
15835: $this->gradients[$n] = array();
15836: $this->gradients[$n]['type'] = 6;
15837: $this->gradients[$n]['coords'] = array();
15838: $this->gradients[$n]['antialias'] = $antialias;
15839: $this->gradients[$n]['colors'] = array();
15840: $this->gradients[$n]['transparency'] = false;
15841:
15842: if (!isset($coords[0]['f'])) {
15843:
15844: if (!isset($col1[1])) {
15845: $col1[1] = $col1[2] = $col1[0];
15846: }
15847: if (!isset($col2[1])) {
15848: $col2[1] = $col2[2] = $col2[0];
15849: }
15850: if (!isset($col3[1])) {
15851: $col3[1] = $col3[2] = $col3[0];
15852: }
15853: if (!isset($col4[1])) {
15854: $col4[1] = $col4[2] = $col4[0];
15855: }
15856: $patch_array[0]['f'] = 0;
15857: $patch_array[0]['points'] = $coords;
15858: $patch_array[0]['colors'][0]['r'] = $col1[0];
15859: $patch_array[0]['colors'][0]['g'] = $col1[1];
15860: $patch_array[0]['colors'][0]['b'] = $col1[2];
15861: $patch_array[0]['colors'][1]['r'] = $col2[0];
15862: $patch_array[0]['colors'][1]['g'] = $col2[1];
15863: $patch_array[0]['colors'][1]['b'] = $col2[2];
15864: $patch_array[0]['colors'][2]['r'] = $col3[0];
15865: $patch_array[0]['colors'][2]['g'] = $col3[1];
15866: $patch_array[0]['colors'][2]['b'] = $col3[2];
15867: $patch_array[0]['colors'][3]['r'] = $col4[0];
15868: $patch_array[0]['colors'][3]['g'] = $col4[1];
15869: $patch_array[0]['colors'][3]['b'] = $col4[2];
15870: } else {
15871:
15872: $patch_array = $coords;
15873: }
15874: $bpcd = 65535;
15875:
15876: $this->gradients[$n]['stream'] = '';
15877: $count_patch = count($patch_array);
15878: for ($i=0; $i < $count_patch; ++$i) {
15879: $this->gradients[$n]['stream'] .= chr($patch_array[$i]['f']);
15880: $count_points = count($patch_array[$i]['points']);
15881: for ($j=0; $j < $count_points; ++$j) {
15882:
15883: $patch_array[$i]['points'][$j] = (($patch_array[$i]['points'][$j] - $coords_min) / ($coords_max - $coords_min)) * $bpcd;
15884: if ($patch_array[$i]['points'][$j] < 0) {
15885: $patch_array[$i]['points'][$j] = 0;
15886: }
15887: if ($patch_array[$i]['points'][$j] > $bpcd) {
15888: $patch_array[$i]['points'][$j] = $bpcd;
15889: }
15890: $this->gradients[$n]['stream'] .= chr(floor($patch_array[$i]['points'][$j] / 256));
15891: $this->gradients[$n]['stream'] .= chr(floor($patch_array[$i]['points'][$j] % 256));
15892: }
15893: $count_cols = count($patch_array[$i]['colors']);
15894: for ($j=0; $j < $count_cols; ++$j) {
15895:
15896: $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['r']);
15897: $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['g']);
15898: $this->gradients[$n]['stream'] .= chr($patch_array[$i]['colors'][$j]['b']);
15899: }
15900: }
15901:
15902: $this->_out('/Sh'.$n.' sh');
15903:
15904: $this->_out('Q');
15905: }
15906:
15907: 15908: 15909: 15910: 15911: 15912: 15913: 15914: 15915: 15916:
15917: protected function Clip($x, $y, $w, $h) {
15918: if ($this->rtl) {
15919: $x = $this->w - $x - $w;
15920: }
15921:
15922: $s = 'q';
15923:
15924: $s .= sprintf(' %.2F %.2F %.2F %.2F re W n', $x*$this->k, ($this->h-$y)*$this->k, $w*$this->k, -$h*$this->k);
15925:
15926: $s .= sprintf(' %.3F 0 0 %.3F %.3F %.3F cm', $w*$this->k, $h*$this->k, $x*$this->k, ($this->h-($y+$h))*$this->k);
15927: $this->_out($s);
15928: }
15929:
15930: 15931: 15932: 15933: 15934: 15935: 15936: 15937: 15938: 15939: 15940:
15941: public function Gradient($type, $coords, $stops, $background=array(), $antialias=false) {
15942: $n = count($this->gradients) + 1;
15943: $this->gradients[$n] = array();
15944: $this->gradients[$n]['type'] = $type;
15945: $this->gradients[$n]['coords'] = $coords;
15946: $this->gradients[$n]['antialias'] = $antialias;
15947: $this->gradients[$n]['colors'] = array();
15948: $this->gradients[$n]['transparency'] = false;
15949:
15950: $numcolspace = count($stops[0]['color']);
15951: $bcolor = array_values($background);
15952: switch($numcolspace) {
15953: case 4: {
15954: $this->gradients[$n]['colspace'] = 'DeviceCMYK';
15955: if (!empty($background)) {
15956: $this->gradients[$n]['background'] = sprintf('%.3F %.3F %.3F %.3F', $bcolor[0]/100, $bcolor[1]/100, $bcolor[2]/100, $bcolor[3]/100);
15957: }
15958: break;
15959: }
15960: case 3: {
15961: $this->gradients[$n]['colspace'] = 'DeviceRGB';
15962: if (!empty($background)) {
15963: $this->gradients[$n]['background'] = sprintf('%.3F %.3F %.3F', $bcolor[0]/255, $bcolor[1]/255, $bcolor[2]/255);
15964: }
15965: break;
15966: }
15967: case 1: {
15968: $this->gradients[$n]['colspace'] = 'DeviceGray';
15969: if (!empty($background)) {
15970: $this->gradients[$n]['background'] = sprintf('%.3F', $bcolor[0]/255);
15971: }
15972: break;
15973: }
15974: }
15975: $num_stops = count($stops);
15976: $last_stop_id = $num_stops - 1;
15977: foreach ($stops as $key => $stop) {
15978: $this->gradients[$n]['colors'][$key] = array();
15979:
15980: if (isset($stop['offset'])) {
15981: $this->gradients[$n]['colors'][$key]['offset'] = $stop['offset'];
15982: } else {
15983: if ($key == 0) {
15984: $this->gradients[$n]['colors'][$key]['offset'] = 0;
15985: } elseif ($key == $last_stop_id) {
15986: $this->gradients[$n]['colors'][$key]['offset'] = 1;
15987: } else {
15988: $offsetstep = (1 - $this->gradients[$n]['colors'][($key - 1)]['offset']) / ($num_stops - $key);
15989: $this->gradients[$n]['colors'][$key]['offset'] = $this->gradients[$n]['colors'][($key - 1)]['offset'] + $offsetstep;
15990: }
15991: }
15992: if (isset($stop['opacity'])) {
15993: $this->gradients[$n]['colors'][$key]['opacity'] = $stop['opacity'];
15994: if ($stop['opacity'] < 1) {
15995: $this->gradients[$n]['transparency'] = true;
15996: }
15997: } else {
15998: $this->gradients[$n]['colors'][$key]['opacity'] = 1;
15999: }
16000:
16001: if (isset($stop['exponent'])) {
16002: $this->gradients[$n]['colors'][$key]['exponent'] = $stop['exponent'];
16003: } else {
16004: $this->gradients[$n]['colors'][$key]['exponent'] = 1;
16005: }
16006:
16007: $color = array_values($stop['color']);
16008: switch($numcolspace) {
16009: case 4: {
16010: $this->gradients[$n]['colors'][$key]['color'] = sprintf('%.3F %.3F %.3F %.3F', $color[0]/100, $color[1]/100, $color[2]/100, $color[3]/100);
16011: break;
16012: }
16013: case 3: {
16014: $this->gradients[$n]['colors'][$key]['color'] = sprintf('%.3F %.3F %.3F', $color[0]/255, $color[1]/255, $color[2]/255);
16015: break;
16016: }
16017: case 1: {
16018: $this->gradients[$n]['colors'][$key]['color'] = sprintf('%.3F', $color[0]/255);
16019: break;
16020: }
16021: }
16022: }
16023: if ($this->gradients[$n]['transparency']) {
16024:
16025: $this->_out('/TGS'.$n.' gs');
16026: }
16027:
16028: $this->_out('/Sh'.$n.' sh');
16029:
16030: $this->_out('Q');
16031: }
16032:
16033: 16034: 16035: 16036: 16037: 16038:
16039: function _putshaders() {
16040: $idt = count($this->gradients);
16041: foreach ($this->gradients as $id => $grad) {
16042: if (($grad['type'] == 2) OR ($grad['type'] == 3)) {
16043: $fc = $this->_newobj();
16044: $out = '<<';
16045: $out .= ' /FunctionType 3';
16046: $out .= ' /Domain [0 1]';
16047: $functions = '';
16048: $bounds = '';
16049: $encode = '';
16050: $i = 1;
16051: $num_cols = count($grad['colors']);
16052: $lastcols = $num_cols - 1;
16053: for ($i = 1; $i < $num_cols; ++$i) {
16054: $functions .= ($fc + $i).' 0 R ';
16055: if ($i < $lastcols) {
16056: $bounds .= sprintf('%.3F ', $grad['colors'][$i]['offset']);
16057: }
16058: $encode .= '0 1 ';
16059: }
16060: $out .= ' /Functions ['.trim($functions).']';
16061: $out .= ' /Bounds ['.trim($bounds).']';
16062: $out .= ' /Encode ['.trim($encode).']';
16063: $out .= ' >>';
16064: $out .= "\n".'endobj';
16065: $this->_out($out);
16066: for ($i = 1; $i < $num_cols; ++$i) {
16067: $this->_newobj();
16068: $out = '<<';
16069: $out .= ' /FunctionType 2';
16070: $out .= ' /Domain [0 1]';
16071: $out .= ' /C0 ['.$grad['colors'][($i - 1)]['color'].']';
16072: $out .= ' /C1 ['.$grad['colors'][$i]['color'].']';
16073: $out .= ' /N '.$grad['colors'][$i]['exponent'];
16074: $out .= ' >>';
16075: $out .= "\n".'endobj';
16076: $this->_out($out);
16077: }
16078:
16079: if ($grad['transparency']) {
16080: $ft = $this->_newobj();
16081: $out = '<<';
16082: $out .= ' /FunctionType 3';
16083: $out .= ' /Domain [0 1]';
16084: $functions = '';
16085: $i = 1;
16086: $num_cols = count($grad['colors']);
16087: for ($i = 1; $i < $num_cols; ++$i) {
16088: $functions .= ($ft + $i).' 0 R ';
16089: }
16090: $out .= ' /Functions ['.trim($functions).']';
16091: $out .= ' /Bounds ['.trim($bounds).']';
16092: $out .= ' /Encode ['.trim($encode).']';
16093: $out .= ' >>';
16094: $out .= "\n".'endobj';
16095: $this->_out($out);
16096: for ($i = 1; $i < $num_cols; ++$i) {
16097: $this->_newobj();
16098: $out = '<<';
16099: $out .= ' /FunctionType 2';
16100: $out .= ' /Domain [0 1]';
16101: $out .= ' /C0 ['.$grad['colors'][($i - 1)]['opacity'].']';
16102: $out .= ' /C1 ['.$grad['colors'][$i]['opacity'].']';
16103: $out .= ' /N '.$grad['colors'][$i]['exponent'];
16104: $out .= ' >>';
16105: $out .= "\n".'endobj';
16106: $this->_out($out);
16107: }
16108: }
16109: }
16110:
16111: $this->_newobj();
16112: $out = '<< /ShadingType '.$grad['type'];
16113: if (isset($grad['colspace'])) {
16114: $out .= ' /ColorSpace /'.$grad['colspace'];
16115: } else {
16116: $out .= ' /ColorSpace /DeviceRGB';
16117: }
16118: if (isset($grad['background']) AND !empty($grad['background'])) {
16119: $out .= ' /Background ['.$grad['background'].']';
16120: }
16121: if (isset($grad['antialias']) AND ($grad['antialias'] === true)) {
16122: $out .= ' /AntiAlias true';
16123: }
16124: if ($grad['type'] == 2) {
16125: $out .= ' '.sprintf('/Coords [%.3F %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3]);
16126: $out .= ' /Domain [0 1]';
16127: $out .= ' /Function '.$fc.' 0 R';
16128: $out .= ' /Extend [true true]';
16129: $out .= ' >>';
16130: } elseif ($grad['type'] == 3) {
16131:
16132:
16133: $out .= ' '.sprintf('/Coords [%.3F %.3F 0 %.3F %.3F %.3F]', $grad['coords'][0], $grad['coords'][1], $grad['coords'][2], $grad['coords'][3], $grad['coords'][4]);
16134: $out .= ' /Domain [0 1]';
16135: $out .= ' /Function '.$fc.' 0 R';
16136: $out .= ' /Extend [true true]';
16137: $out .= ' >>';
16138: } elseif ($grad['type'] == 6) {
16139: $out .= ' /BitsPerCoordinate 16';
16140: $out .= ' /BitsPerComponent 8';
16141: $out .= ' /Decode[0 1 0 1 0 1 0 1 0 1]';
16142: $out .= ' /BitsPerFlag 8';
16143: $stream = $this->_getrawstream($grad['stream']);
16144: $out .= ' /Length '.strlen($stream);
16145: $out .= ' >>';
16146: $out .= ' stream'."\n".$stream."\n".'endstream';
16147: }
16148: $out .= "\n".'endobj';
16149: $this->_out($out);
16150: if ($grad['transparency']) {
16151: $shading_transparency = preg_replace('/\/ColorSpace \/[^\s]+/si', '/ColorSpace /DeviceGray', $out);
16152: $shading_transparency = preg_replace('/\/Function [0-9]+ /si', '/Function '.$ft.' ', $shading_transparency);
16153: }
16154: $this->gradients[$id]['id'] = $this->n;
16155:
16156: $this->_newobj();
16157: $out = '<< /Type /Pattern /PatternType 2';
16158: $out .= ' /Shading '.$this->gradients[$id]['id'].' 0 R';
16159: $out .= ' >>';
16160: $out .= "\n".'endobj';
16161: $this->_out($out);
16162: $this->gradients[$id]['pattern'] = $this->n;
16163:
16164: if ($grad['transparency']) {
16165:
16166: $idgs = $id + $idt;
16167: $this->_newobj();
16168: $this->_out($shading_transparency);
16169: $this->gradients[$idgs]['id'] = $this->n;
16170: $this->_newobj();
16171: $out = '<< /Type /Pattern /PatternType 2';
16172: $out .= ' /Shading '.$this->gradients[$idgs]['id'].' 0 R';
16173: $out .= ' >>';
16174: $out .= "\n".'endobj';
16175: $this->_out($out);
16176: $this->gradients[$idgs]['pattern'] = $this->n;
16177:
16178: $oid = $this->_newobj();
16179: $this->xobjects['LX'.$oid] = array('n' => $oid);
16180: $filter = '';
16181: $stream = 'q /a0 gs /Pattern cs /p'.$idgs.' scn 0 0 '.$this->wPt.' '.$this->hPt.' re f Q';
16182: if ($this->compress) {
16183: $filter = ' /Filter /FlateDecode';
16184: $stream = gzcompress($stream);
16185: }
16186: $stream = $this->_getrawstream($stream);
16187: $out = '<< /Type /XObject /Subtype /Form /FormType 1'.$filter;
16188: $out .= ' /Length '.strlen($stream);
16189: $rect = sprintf('%.2F %.2F', $this->wPt, $this->hPt);
16190: $out .= ' /BBox [0 0 '.$rect.']';
16191: $out .= ' /Group << /Type /Group /S /Transparency /CS /DeviceGray >>';
16192: $out .= ' /Resources <<';
16193: $out .= ' /ExtGState << /a0 << /ca 1 /CA 1 >> >>';
16194: $out .= ' /Pattern << /p'.$idgs.' '.$this->gradients[$idgs]['pattern'].' 0 R >>';
16195: $out .= ' >>';
16196: $out .= ' >> ';
16197: $out .= ' stream'."\n".$stream."\n".'endstream';
16198: $out .= "\n".'endobj';
16199: $this->_out($out);
16200:
16201: $this->_newobj();
16202: $out = '<< /Type /Mask /S /Luminosity /G '.($this->n - 1).' 0 R >>'."\n".'endobj';
16203: $this->_out($out);
16204:
16205: $this->_newobj();
16206: $out = '<< /Type /ExtGState /SMask '.($this->n - 1).' 0 R /AIS false >>'."\n".'endobj';
16207: $this->_out($out);
16208: $this->extgstates[] = array('n' => $this->n, 'name' => 'TGS'.$id);
16209: }
16210: }
16211: }
16212:
16213: 16214: 16215: 16216: 16217: 16218: 16219: 16220: 16221: 16222: 16223: 16224: 16225: 16226: 16227:
16228: public function PieSector($xc, $yc, $r, $a, $b, $style='FD', $cw=true, $o=90) {
16229: $this->PieSectorXY($xc, $yc, $r, $r, $a, $b, $style, $cw, $o);
16230: }
16231:
16232: 16233: 16234: 16235: 16236: 16237: 16238: 16239: 16240: 16241: 16242: 16243: 16244: 16245: 16246: 16247: 16248:
16249: public function PieSectorXY($xc, $yc, $rx, $ry, $a, $b, $style='FD', $cw=false, $o=0, $nc=2) {
16250: if ($this->rtl) {
16251: $xc = $this->w - $xc;
16252: }
16253: $op = $this->getPathPaintOperator($style);
16254: if ($op == 'f') {
16255: $line_style = array();
16256: }
16257: if ($cw) {
16258: $d = $b;
16259: $b = 360 - $a + $o;
16260: $a = 360 - $d + $o;
16261: } else {
16262: $b += $o;
16263: $a += $o;
16264: }
16265: $this->_outellipticalarc($xc, $yc, $rx, $ry, 0, $a, $b, true, $nc);
16266: $this->_out($op);
16267: }
16268:
16269: 16270: 16271: 16272: 16273: 16274: 16275: 16276: 16277: 16278: 16279: 16280: 16281: 16282: 16283: 16284: 16285: 16286: 16287: 16288:
16289: public function ImageEps($file, $x='', $y='', $w=0, $h=0, $link='', $useBoundingBox=true, $align='', $palign='', $border=0, $fitonpage=false) {
16290: if ($this->rasterize_vector_images AND ($w > 0) AND ($h > 0)) {
16291:
16292: return $this->Image($file, $x, $y, $w, $h, 'EPS', $link, $align, true, 300, $palign, false, false, $border, false, false, $fitonpage);
16293: }
16294: if ($x === '') {
16295: $x = $this->x;
16296: }
16297: if ($y === '') {
16298: $y = $this->y;
16299: }
16300:
16301: $this->checkPageRegions($h, $x, $y);
16302: $k = $this->k;
16303: $data = file_get_contents($file);
16304: if ($data === false) {
16305: $this->Error('EPS file not found: '.$file);
16306: }
16307: $regs = array();
16308:
16309: preg_match("/%%Creator:([^\r\n]+)/", $data, $regs);
16310: if (count($regs) > 1) {
16311: $version_str = trim($regs[1]);
16312: if (strpos($version_str, 'Adobe Illustrator') !== false) {
16313: $versexp = explode(' ', $version_str);
16314: $version = (float)array_pop($versexp);
16315: if ($version >= 9) {
16316: $this->Error('This version of Adobe Illustrator file is not supported: '.$file);
16317: }
16318: }
16319: }
16320:
16321: $start = strpos($data, '%!PS-Adobe');
16322: if ($start > 0) {
16323: $data = substr($data, $start);
16324: }
16325:
16326: preg_match("/%%BoundingBox:([^\r\n]+)/", $data, $regs);
16327: if (count($regs) > 1) {
16328: list($x1, $y1, $x2, $y2) = explode(' ', trim($regs[1]));
16329: } else {
16330: $this->Error('No BoundingBox found in EPS file: '.$file);
16331: }
16332: $start = strpos($data, '%%EndSetup');
16333: if ($start === false) {
16334: $start = strpos($data, '%%EndProlog');
16335: }
16336: if ($start === false) {
16337: $start = strpos($data, '%%BoundingBox');
16338: }
16339: $data = substr($data, $start);
16340: $end = strpos($data, '%%PageTrailer');
16341: if ($end===false) {
16342: $end = strpos($data, 'showpage');
16343: }
16344: if ($end) {
16345: $data = substr($data, 0, $end);
16346: }
16347:
16348: if (($w <= 0) AND ($h <= 0)) {
16349: $w = ($x2 - $x1) / $k;
16350: $h = ($y2 - $y1) / $k;
16351: } elseif ($w <= 0) {
16352: $w = ($x2-$x1) / $k * ($h / (($y2 - $y1) / $k));
16353: } elseif ($h <= 0) {
16354: $h = ($y2 - $y1) / $k * ($w / (($x2 - $x1) / $k));
16355: }
16356:
16357: $this->fitBlock($w, $h, $x, $y, $fitonpage);
16358: if ($this->rasterize_vector_images) {
16359:
16360: return $this->Image($file, $x, $y, $w, $h, 'EPS', $link, $align, true, 300, $palign, false, false, $border, false, false, $fitonpage);
16361: }
16362:
16363: $scale_x = $w / (($x2 - $x1) / $k);
16364: $scale_y = $h / (($y2 - $y1) / $k);
16365:
16366: $this->img_rb_y = $y + $h;
16367:
16368: if ($this->rtl) {
16369: if ($palign == 'L') {
16370: $ximg = $this->lMargin;
16371: } elseif ($palign == 'C') {
16372: $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
16373: } elseif ($palign == 'R') {
16374: $ximg = $this->w - $this->rMargin - $w;
16375: } else {
16376: $ximg = $x - $w;
16377: }
16378: $this->img_rb_x = $ximg;
16379: } else {
16380: if ($palign == 'L') {
16381: $ximg = $this->lMargin;
16382: } elseif ($palign == 'C') {
16383: $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
16384: } elseif ($palign == 'R') {
16385: $ximg = $this->w - $this->rMargin - $w;
16386: } else {
16387: $ximg = $x;
16388: }
16389: $this->img_rb_x = $ximg + $w;
16390: }
16391: if ($useBoundingBox) {
16392: $dx = $ximg * $k - $x1;
16393: $dy = $y * $k - $y1;
16394: } else {
16395: $dx = $ximg * $k;
16396: $dy = $y * $k;
16397: }
16398:
16399: $this->_out('q'.$this->epsmarker);
16400:
16401: $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', 1, 0, 0, 1, $dx, $dy + ($this->hPt - (2 * $y * $k) - ($y2 - $y1))));
16402:
16403: if (isset($scale_x)) {
16404: $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', $scale_x, 0, 0, $scale_y, $x1 * (1 - $scale_x), $y2 * (1 - $scale_y)));
16405: }
16406:
16407: preg_match('/[\r\n]+/s', $data, $regs);
16408: $lines = explode($regs[0], $data);
16409: $u=0;
16410: $cnt = count($lines);
16411: for ($i=0; $i < $cnt; ++$i) {
16412: $line = $lines[$i];
16413: if (($line == '') OR ($line{0} == '%')) {
16414: continue;
16415: }
16416: $len = strlen($line);
16417: $chunks = explode(' ', $line);
16418: $cmd = array_pop($chunks);
16419:
16420: if (($cmd == 'Xa') OR ($cmd == 'XA')) {
16421: $b = array_pop($chunks);
16422: $g = array_pop($chunks);
16423: $r = array_pop($chunks);
16424: $this->_out(''.$r.' '.$g.' '.$b.' '.($cmd=='Xa'?'rg':'RG'));
16425: continue;
16426: }
16427: switch ($cmd) {
16428: case 'm':
16429: case 'l':
16430: case 'v':
16431: case 'y':
16432: case 'c':
16433: case 'k':
16434: case 'K':
16435: case 'g':
16436: case 'G':
16437: case 's':
16438: case 'S':
16439: case 'J':
16440: case 'j':
16441: case 'w':
16442: case 'M':
16443: case 'd':
16444: case 'n': {
16445: $this->_out($line);
16446: break;
16447: }
16448: case 'x': {
16449: list($c,$m,$y,$k) = $chunks;
16450: $this->_out(''.$c.' '.$m.' '.$y.' '.$k.' k');
16451: break;
16452: }
16453: case 'X': {
16454: list($c,$m,$y,$k) = $chunks;
16455: $this->_out(''.$c.' '.$m.' '.$y.' '.$k.' K');
16456: break;
16457: }
16458: case 'Y':
16459: case 'N':
16460: case 'V':
16461: case 'L':
16462: case 'C': {
16463: $line{$len-1} = strtolower($cmd);
16464: $this->_out($line);
16465: break;
16466: }
16467: case 'b':
16468: case 'B': {
16469: $this->_out($cmd . '*');
16470: break;
16471: }
16472: case 'f':
16473: case 'F': {
16474: if ($u > 0) {
16475: $isU = false;
16476: $max = min($i+5, $cnt);
16477: for ($j=$i+1; $j < $max; ++$j) {
16478: $isU = ($isU OR (($lines[$j] == 'U') OR ($lines[$j] == '*U')));
16479: }
16480: if ($isU) {
16481: $this->_out('f*');
16482: }
16483: } else {
16484: $this->_out('f*');
16485: }
16486: break;
16487: }
16488: case '*u': {
16489: ++$u;
16490: break;
16491: }
16492: case '*U': {
16493: --$u;
16494: break;
16495: }
16496: }
16497: }
16498:
16499: $this->_out($this->epsmarker.'Q');
16500: if (!empty($border)) {
16501: $bx = $this->x;
16502: $by = $this->y;
16503: $this->x = $ximg;
16504: if ($this->rtl) {
16505: $this->x += $w;
16506: }
16507: $this->y = $y;
16508: $this->Cell($w, $h, '', $border, 0, '', 0, '', 0, true);
16509: $this->x = $bx;
16510: $this->y = $by;
16511: }
16512: if ($link) {
16513: $this->Link($ximg, $y, $w, $h, $link, 0);
16514: }
16515:
16516: switch($align) {
16517: case 'T':{
16518: $this->y = $y;
16519: $this->x = $this->img_rb_x;
16520: break;
16521: }
16522: case 'M':{
16523: $this->y = $y + round($h/2);
16524: $this->x = $this->img_rb_x;
16525: break;
16526: }
16527: case 'B':{
16528: $this->y = $this->img_rb_y;
16529: $this->x = $this->img_rb_x;
16530: break;
16531: }
16532: case 'N':{
16533: $this->SetY($this->img_rb_y);
16534: break;
16535: }
16536: default:{
16537: break;
16538: }
16539: }
16540: $this->endlinex = $this->img_rb_x;
16541: }
16542:
16543: 16544: 16545: 16546: 16547:
16548: public function setBarcode($bc='') {
16549: $this->barcode = $bc;
16550: }
16551:
16552: 16553: 16554: 16555: 16556: 16557:
16558: public function getBarcode() {
16559: return $this->barcode;
16560: }
16561:
16562: 16563: 16564: 16565: 16566: 16567: 16568: 16569: 16570: 16571: 16572: 16573: 16574: 16575: 16576: 16577: 16578: 16579: 16580: 16581: 16582: 16583: 16584: 16585: 16586: 16587: 16588: 16589: 16590: 16591:
16592: public function write1DBarcode($code, $type, $x='', $y='', $w='', $h='', $xres='', $style='', $align='') {
16593: if ($this->empty_string(trim($code))) {
16594: return;
16595: }
16596: require_once(dirname(__FILE__).'/barcodes.php');
16597:
16598: $gvars = $this->getGraphicVars();
16599:
16600: $barcodeobj = new TCPDFBarcode($code, $type);
16601: $arrcode = $barcodeobj->getBarcodeArray();
16602: if ($arrcode === false) {
16603: $this->Error('Error in 1D barcode string');
16604: }
16605:
16606: if (!isset($style['position'])) {
16607: $style['position'] = '';
16608: } elseif ($style['position'] == 'S') {
16609:
16610: $style['position'] = '';
16611: $style['stretch'] = true;
16612: }
16613: if (!isset($style['fitwidth'])) {
16614: if (!isset($style['stretch'])) {
16615: $style['fitwidth'] = true;
16616: } else {
16617: $style['fitwidth'] = false;
16618: }
16619: }
16620: if ($style['fitwidth']) {
16621:
16622: $style['stretch'] = false;
16623: }
16624: if (!isset($style['stretch'])) {
16625: if (($w === '') OR ($w <= 0)) {
16626: $style['stretch'] = false;
16627: } else {
16628: $style['stretch'] = true;
16629: }
16630: }
16631: if (!isset($style['fgcolor'])) {
16632: $style['fgcolor'] = array(0,0,0);
16633: }
16634: if (!isset($style['bgcolor'])) {
16635: $style['bgcolor'] = false;
16636: }
16637: if (!isset($style['border'])) {
16638: $style['border'] = false;
16639: }
16640: $fontsize = 0;
16641: if (!isset($style['text'])) {
16642: $style['text'] = false;
16643: }
16644: if ($style['text'] AND isset($style['font'])) {
16645: if (isset($style['fontsize'])) {
16646: $fontsize = $style['fontsize'];
16647: }
16648: $this->SetFont($style['font'], '', $fontsize);
16649: }
16650: if (!isset($style['stretchtext'])) {
16651: $style['stretchtext'] = 4;
16652: }
16653: if ($x === '') {
16654: $x = $this->x;
16655: }
16656: if ($y === '') {
16657: $y = $this->y;
16658: }
16659:
16660: $this->checkPageRegions($h, $x, $y);
16661: if (($w === '') OR ($w <= 0)) {
16662: if ($this->rtl) {
16663: $w = $x - $this->lMargin;
16664: } else {
16665: $w = $this->w - $this->rMargin - $x;
16666: }
16667: }
16668:
16669: if (!isset($style['padding'])) {
16670: $padding = 0;
16671: } elseif ($style['padding'] === 'auto') {
16672: $padding = 10 * ($w / ($arrcode['maxw'] + 20));
16673: } else {
16674: $padding = floatval($style['padding']);
16675: }
16676:
16677: if (!isset($style['hpadding'])) {
16678: $hpadding = $padding;
16679: } elseif ($style['hpadding'] === 'auto') {
16680: $hpadding = 10 * ($w / ($arrcode['maxw'] + 20));
16681: } else {
16682: $hpadding = floatval($style['hpadding']);
16683: }
16684:
16685: if (!isset($style['vpadding'])) {
16686: $vpadding = $padding;
16687: } elseif ($style['vpadding'] === 'auto') {
16688: $vpadding = ($hpadding / 2);
16689: } else {
16690: $vpadding = floatval($style['vpadding']);
16691: }
16692:
16693: $max_xres = ($w - (2 * $hpadding)) / $arrcode['maxw'];
16694: if ($style['stretch']) {
16695: $xres = $max_xres;
16696: } else {
16697: if ($this->empty_string($xres)) {
16698: $xres = (0.141 * $this->k);
16699: }
16700: if ($xres > $max_xres) {
16701:
16702: $xres = $max_xres;
16703: }
16704: if ((isset($style['padding']) AND ($style['padding'] === 'auto'))
16705: OR (isset($style['hpadding']) AND ($style['hpadding'] === 'auto'))) {
16706: $hpadding = 10 * $xres;
16707: if (isset($style['vpadding']) AND ($style['vpadding'] === 'auto')) {
16708: $vpadding = ($hpadding / 2);
16709: }
16710: }
16711: }
16712: if ($style['fitwidth']) {
16713: $wold = $w;
16714: $w = (($arrcode['maxw'] * $xres) + (2 * $hpadding));
16715: if (isset($style['cellfitalign'])) {
16716: switch ($style['cellfitalign']) {
16717: case 'L': {
16718: if ($this->rtl) {
16719: $x -= ($wold - $w);
16720: }
16721: break;
16722: }
16723: case 'R': {
16724: if (!$this->rtl) {
16725: $x += ($wold - $w);
16726: }
16727: break;
16728: }
16729: case 'C': {
16730: if ($this->rtl) {
16731: $x -= (($wold - $w) / 2);
16732: } else {
16733: $x += (($wold - $w) / 2);
16734: }
16735: break;
16736: }
16737: default : {
16738: break;
16739: }
16740: }
16741: }
16742: }
16743: $text_height = ($this->cell_height_ratio * $fontsize / $this->k);
16744:
16745: if (($h === '') OR ($h <= 0)) {
16746:
16747: $h = (($arrcode['maxw'] * $xres) / 3) + (2 * $vpadding) + $text_height;
16748: }
16749: $barh = $h - $text_height - (2 * $vpadding);
16750: if ($barh <=0) {
16751:
16752: if ($text_height > $h) {
16753: $fontsize = (($h * $this->k) / (4 * $this->cell_height_ratio));
16754: $text_height = ($this->cell_height_ratio * $fontsize / $this->k);
16755: $this->SetFont($style['font'], '', $fontsize);
16756: }
16757: if ($vpadding > 0) {
16758: $vpadding = (($h - $text_height) / 4);
16759: }
16760: $barh = $h - $text_height - (2 * $vpadding);
16761: }
16762:
16763: $this->fitBlock($w, $h, $x, $y, false);
16764:
16765: $this->img_rb_y = $y + $h;
16766:
16767: if ($this->rtl) {
16768: if ($style['position'] == 'L') {
16769: $xpos = $this->lMargin;
16770: } elseif ($style['position'] == 'C') {
16771: $xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
16772: } elseif ($style['position'] == 'R') {
16773: $xpos = $this->w - $this->rMargin - $w;
16774: } else {
16775: $xpos = $x - $w;
16776: }
16777: $this->img_rb_x = $xpos;
16778: } else {
16779: if ($style['position'] == 'L') {
16780: $xpos = $this->lMargin;
16781: } elseif ($style['position'] == 'C') {
16782: $xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
16783: } elseif ($style['position'] == 'R') {
16784: $xpos = $this->w - $this->rMargin - $w;
16785: } else {
16786: $xpos = $x;
16787: }
16788: $this->img_rb_x = $xpos + $w;
16789: }
16790: $xpos_rect = $xpos;
16791: if (!isset($style['align'])) {
16792: $style['align'] = 'C';
16793: }
16794: switch ($style['align']) {
16795: case 'L': {
16796: $xpos = $xpos_rect + $hpadding;
16797: break;
16798: }
16799: case 'R': {
16800: $xpos = $xpos_rect + ($w - ($arrcode['maxw'] * $xres)) - $hpadding;
16801: break;
16802: }
16803: case 'C':
16804: default : {
16805: $xpos = $xpos_rect + (($w - ($arrcode['maxw'] * $xres)) / 2);
16806: break;
16807: }
16808: }
16809: $xpos_text = $xpos;
16810:
16811: $tempRTL = $this->rtl;
16812: $this->rtl = false;
16813:
16814: if ($style['bgcolor']) {
16815: $this->Rect($xpos_rect, $y, $w, $h, $style['border'] ? 'DF' : 'F', '', $style['bgcolor']);
16816: } elseif ($style['border']) {
16817: $this->Rect($xpos_rect, $y, $w, $h, 'D');
16818: }
16819:
16820: $this->SetDrawColorArray($style['fgcolor']);
16821: $this->SetTextColorArray($style['fgcolor']);
16822:
16823: foreach ($arrcode['bcode'] as $k => $v) {
16824: $bw = ($v['w'] * $xres);
16825: if ($v['t']) {
16826:
16827: $ypos = $y + $vpadding + ($v['p'] * $barh / $arrcode['maxh']);
16828: $this->Rect($xpos, $ypos, $bw, ($v['h'] * $barh / $arrcode['maxh']), 'F', array(), $style['fgcolor']);
16829: }
16830: $xpos += $bw;
16831: }
16832:
16833: if ($style['text']) {
16834: if (isset($style['label']) AND !$this->empty_string($style['label'])) {
16835: $label = $style['label'];
16836: } else {
16837: $label = $code;
16838: }
16839: $txtwidth = ($arrcode['maxw'] * $xres);
16840: if ($this->GetStringWidth($label) > $txtwidth) {
16841: $style['stretchtext'] = 2;
16842: }
16843:
16844: $this->x = $xpos_text;
16845: $this->y = $y + $vpadding + $barh;
16846: $cellpadding = $this->cell_padding;
16847: $this->SetCellPadding(0);
16848: $this->Cell($txtwidth, '', $label, 0, 0, 'C', 0, '', $style['stretchtext'], false, 'T', 'T');
16849: $this->cell_padding = $cellpadding;
16850: }
16851:
16852: $this->rtl = $tempRTL;
16853:
16854: $this->setGraphicVars($gvars);
16855:
16856: switch($align) {
16857: case 'T':{
16858: $this->y = $y;
16859: $this->x = $this->img_rb_x;
16860: break;
16861: }
16862: case 'M':{
16863: $this->y = $y + round($h / 2);
16864: $this->x = $this->img_rb_x;
16865: break;
16866: }
16867: case 'B':{
16868: $this->y = $this->img_rb_y;
16869: $this->x = $this->img_rb_x;
16870: break;
16871: }
16872: case 'N':{
16873: $this->SetY($this->img_rb_y);
16874: break;
16875: }
16876: default:{
16877: break;
16878: }
16879: }
16880: $this->endlinex = $this->img_rb_x;
16881: }
16882:
16883: 16884: 16885: 16886: 16887: 16888: 16889: 16890: 16891: 16892: 16893: 16894: 16895: 16896: 16897:
16898: public function writeBarcode($x, $y, $w, $h, $type, $style, $font, $xres, $code) {
16899:
16900: $xres = 1 / $xres;
16901: $newstyle = array(
16902: 'position' => '',
16903: 'align' => '',
16904: 'stretch' => false,
16905: 'fitwidth' => false,
16906: 'cellfitalign' => '',
16907: 'border' => false,
16908: 'padding' => 0,
16909: 'fgcolor' => array(0,0,0),
16910: 'bgcolor' => false,
16911: 'text' => true,
16912: 'font' => $font,
16913: 'fontsize' => 8,
16914: 'stretchtext' => 4
16915: );
16916: if ($style & 1) {
16917: $newstyle['border'] = true;
16918: }
16919: if ($style & 2) {
16920: $newstyle['bgcolor'] = false;
16921: }
16922: if ($style & 4) {
16923: $newstyle['position'] = 'C';
16924: } elseif ($style & 8) {
16925: $newstyle['position'] = 'L';
16926: } elseif ($style & 16) {
16927: $newstyle['position'] = 'R';
16928: }
16929: if ($style & 128) {
16930: $newstyle['text'] = true;
16931: }
16932: if ($style & 256) {
16933: $newstyle['stretchtext'] = 4;
16934: }
16935: $this->write1DBarcode($code, $type, $x, $y, $w, $h, $xres, $newstyle, '');
16936: }
16937:
16938: 16939: 16940: 16941: 16942: 16943: 16944: 16945: 16946: 16947: 16948: 16949: 16950: 16951: 16952: 16953: 16954: 16955: 16956: 16957: 16958: 16959: 16960: 16961: 16962:
16963: public function write2DBarcode($code, $type, $x='', $y='', $w='', $h='', $style='', $align='', $distort=false) {
16964: if ($this->empty_string(trim($code))) {
16965: return;
16966: }
16967: require_once(dirname(__FILE__).'/2dbarcodes.php');
16968:
16969: $gvars = $this->getGraphicVars();
16970:
16971: $barcodeobj = new TCPDF2DBarcode($code, $type);
16972: $arrcode = $barcodeobj->getBarcodeArray();
16973: if (($arrcode === false) OR empty($arrcode)) {
16974: $this->Error('Error in 2D barcode string');
16975: }
16976:
16977: if (!isset($style['position'])) {
16978: $style['position'] = '';
16979: }
16980: if (!isset($style['fgcolor'])) {
16981: $style['fgcolor'] = array(0,0,0);
16982: }
16983: if (!isset($style['bgcolor'])) {
16984: $style['bgcolor'] = false;
16985: }
16986: if (!isset($style['border'])) {
16987: $style['border'] = false;
16988: }
16989:
16990: if (!isset($style['padding'])) {
16991: $style['padding'] = 0;
16992: } elseif ($style['padding'] === 'auto') {
16993: $style['padding'] = 4;
16994: }
16995: if (!isset($style['hpadding'])) {
16996: $style['hpadding'] = $style['padding'];
16997: } elseif ($style['hpadding'] === 'auto') {
16998: $style['hpadding'] = 4;
16999: }
17000: if (!isset($style['vpadding'])) {
17001: $style['vpadding'] = $style['padding'];
17002: } elseif ($style['vpadding'] === 'auto') {
17003: $style['vpadding'] = 4;
17004: }
17005:
17006: if (!isset($style['module_width'])) {
17007: $style['module_width'] = 1;
17008: }
17009: if (!isset($style['module_height'])) {
17010: $style['module_height'] = 1;
17011: }
17012: if ($x === '') {
17013: $x = $this->x;
17014: }
17015: if ($y === '') {
17016: $y = $this->y;
17017: }
17018:
17019: $this->checkPageRegions($h, $x, $y);
17020:
17021: $rows = $arrcode['num_rows'];
17022: $cols = $arrcode['num_cols'];
17023:
17024: $mw = $style['module_width'];
17025: $mh = $style['module_height'];
17026:
17027: if ($this->rtl) {
17028: $maxw = $x - $this->lMargin;
17029: } else {
17030: $maxw = $this->w - $this->rMargin - $x;
17031: }
17032: $maxh = ($this->h - $this->tMargin - $this->bMargin);
17033: $ratioHW = ($rows * $mh) / ($cols * $mw);
17034: $ratioWH = ($cols * $mw) / ($rows * $mh);
17035: if (!$distort) {
17036: if (($maxw * $ratioHW) > $maxh) {
17037: $maxw = $maxh * $ratioWH;
17038: }
17039: if (($maxh * $ratioWH) > $maxw) {
17040: $maxh = $maxw * $ratioHW;
17041: }
17042: }
17043:
17044: if ($w > $maxw) {
17045: $w = $maxw;
17046: }
17047: if ($h > $maxh) {
17048: $h = $maxh;
17049: }
17050: $hpad = (2 * $style['hpadding']);
17051: $vpad = (2 * $style['vpadding']);
17052:
17053: if ((($w === '') OR ($w <= 0)) AND (($h === '') OR ($h <= 0))) {
17054: $w = ($cols + $hpad) * ($mw / $this->k);
17055: $h = ($rows + $vpad) * ($mh / $this->k);
17056: } elseif (($w === '') OR ($w <= 0)) {
17057: $w = $h * $ratioWH;
17058: } elseif (($h === '') OR ($h <= 0)) {
17059: $h = $w * $ratioHW;
17060: }
17061:
17062: $bw = ($w * $cols) / ($cols + $hpad);
17063: $bh = ($h * $rows) / ($rows + $vpad);
17064:
17065: $cw = $bw / $cols;
17066: $ch = $bh / $rows;
17067: if (!$distort) {
17068: if (($cw / $ch) > ($mw / $mh)) {
17069:
17070: $cw = $ch * $mw / $mh;
17071: $bw = $cw * $cols;
17072: $style['hpadding'] = ($w - $bw) / (2 * $cw);
17073: } else {
17074:
17075: $ch = $cw * $mh / $mw;
17076: $bh = $ch * $rows;
17077: $style['vpadding'] = ($h - $bh) / (2 * $ch);
17078: }
17079: }
17080:
17081: $this->fitBlock($w, $h, $x, $y, false);
17082:
17083: $this->img_rb_y = $y + $h;
17084:
17085: if ($this->rtl) {
17086: if ($style['position'] == 'L') {
17087: $xpos = $this->lMargin;
17088: } elseif ($style['position'] == 'C') {
17089: $xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
17090: } elseif ($style['position'] == 'R') {
17091: $xpos = $this->w - $this->rMargin - $w;
17092: } else {
17093: $xpos = $x - $w;
17094: }
17095: $this->img_rb_x = $xpos;
17096: } else {
17097: if ($style['position'] == 'L') {
17098: $xpos = $this->lMargin;
17099: } elseif ($style['position'] == 'C') {
17100: $xpos = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
17101: } elseif ($style['position'] == 'R') {
17102: $xpos = $this->w - $this->rMargin - $w;
17103: } else {
17104: $xpos = $x;
17105: }
17106: $this->img_rb_x = $xpos + $w;
17107: }
17108: $xstart = $xpos + ($style['hpadding'] * $cw);
17109: $ystart = $y + ($style['vpadding'] * $ch);
17110:
17111: $tempRTL = $this->rtl;
17112: $this->rtl = false;
17113:
17114: if ($style['bgcolor']) {
17115: $this->Rect($xpos, $y, $w, $h, $style['border'] ? 'DF' : 'F', '', $style['bgcolor']);
17116: } elseif ($style['border']) {
17117: $this->Rect($xpos, $y, $w, $h, 'D');
17118: }
17119:
17120: $this->SetDrawColorArray($style['fgcolor']);
17121:
17122:
17123: for ($r = 0; $r < $rows; ++$r) {
17124: $xr = $xstart;
17125:
17126: for ($c = 0; $c < $cols; ++$c) {
17127: if ($arrcode['bcode'][$r][$c] == 1) {
17128:
17129: $this->Rect($xr, $ystart, $cw, $ch, 'F', array(), $style['fgcolor']);
17130: }
17131: $xr += $cw;
17132: }
17133: $ystart += $ch;
17134: }
17135:
17136: $this->rtl = $tempRTL;
17137:
17138: $this->setGraphicVars($gvars);
17139:
17140: switch($align) {
17141: case 'T':{
17142: $this->y = $y;
17143: $this->x = $this->img_rb_x;
17144: break;
17145: }
17146: case 'M':{
17147: $this->y = $y + round($h/2);
17148: $this->x = $this->img_rb_x;
17149: break;
17150: }
17151: case 'B':{
17152: $this->y = $this->img_rb_y;
17153: $this->x = $this->img_rb_x;
17154: break;
17155: }
17156: case 'N':{
17157: $this->SetY($this->img_rb_y);
17158: break;
17159: }
17160: default:{
17161: break;
17162: }
17163: }
17164: $this->endlinex = $this->img_rb_x;
17165: }
17166:
17167: 17168: 17169: 17170: 17171: 17172: 17173: 17174: 17175: 17176: 17177: 17178: 17179: 17180: 17181: 17182: 17183: 17184: 17185:
17186: public function getMargins() {
17187: $ret = array(
17188: 'left' => $this->lMargin,
17189: 'right' => $this->rMargin,
17190: 'top' => $this->tMargin,
17191: 'bottom' => $this->bMargin,
17192: 'header' => $this->header_margin,
17193: 'footer' => $this->footer_margin,
17194: 'cell' => $this->cell_padding,
17195: 'padding_left' => $this->cell_padding['L'],
17196: 'padding_top' => $this->cell_padding['T'],
17197: 'padding_right' => $this->cell_padding['R'],
17198: 'padding_bottom' => $this->cell_padding['B']
17199: );
17200: return $ret;
17201: }
17202:
17203: 17204: 17205: 17206: 17207: 17208: 17209: 17210: 17211: 17212:
17213: public function getOriginalMargins() {
17214: $ret = array(
17215: 'left' => $this->original_lMargin,
17216: 'right' => $this->original_rMargin
17217: );
17218: return $ret;
17219: }
17220:
17221: 17222: 17223: 17224: 17225: 17226:
17227: public function getFontSize() {
17228: return $this->FontSize;
17229: }
17230:
17231: 17232: 17233: 17234: 17235: 17236:
17237: public function getFontSizePt() {
17238: return $this->FontSizePt;
17239: }
17240:
17241: 17242: 17243: 17244: 17245: 17246:
17247: public function getFontFamily() {
17248: return $this->FontFamily;
17249: }
17250:
17251: 17252: 17253: 17254: 17255: 17256:
17257: public function getFontStyle() {
17258: return $this->FontStyle;
17259: }
17260:
17261: 17262: 17263: 17264: 17265: 17266: 17267: 17268:
17269: protected function ($cssdata) {
17270: if (empty($cssdata)) {
17271: return array();
17272: }
17273:
17274: $cssdata = preg_replace('/\/\*[^\*]*\*\//', '', $cssdata);
17275:
17276: $cssdata = preg_replace('/[\s]+/', ' ', $cssdata);
17277:
17278: $cssdata = preg_replace('/[\s]*([;:\{\}]{1})[\s]*/', '\\1', $cssdata);
17279:
17280: $cssdata = preg_replace('/([^\}\{]+)\{\}/', '', $cssdata);
17281:
17282: $cssdata = preg_replace('/@media[\s]+([^\{]*)\{/i', '@media \\1§', $cssdata);
17283: $cssdata = preg_replace('/\}\}/si', '}§', $cssdata);
17284:
17285: $cssdata = trim($cssdata);
17286:
17287: $cssblocks = array();
17288: $matches = array();
17289: if (preg_match_all('/@media[\s]+([^\§]*)§([^§]*)§/i', $cssdata, $matches) > 0) {
17290: foreach ($matches[1] as $key => $type) {
17291: $cssblocks[$type] = $matches[2][$key];
17292: }
17293:
17294: $cssdata = preg_replace('/@media[\s]+([^\§]*)§([^§]*)§/i', '', $cssdata);
17295: }
17296:
17297: if (isset($cssblocks['all']) AND !empty($cssblocks['all'])) {
17298: $cssdata .= $cssblocks['all'];
17299: }
17300: if (isset($cssblocks['print']) AND !empty($cssblocks['print'])) {
17301: $cssdata .= $cssblocks['print'];
17302: }
17303:
17304: $cssblocks = array();
17305: $matches = array();
17306:
17307: if (substr($cssdata, -1) == '}') {
17308:
17309: $cssdata = substr($cssdata, 0, -1);
17310: }
17311: $matches = explode('}', $cssdata);
17312: foreach ($matches as $key => $block) {
17313:
17314: $cssblocks[$key] = explode('{', $block);
17315: if (!isset($cssblocks[$key][1])) {
17316:
17317: unset($cssblocks[$key]);
17318: }
17319: }
17320:
17321: foreach ($cssblocks as $key => $block) {
17322: if (strpos($block[0], ',') > 0) {
17323: $selectors = explode(',', $block[0]);
17324: foreach ($selectors as $sel) {
17325: $cssblocks[] = array(0 => trim($sel), 1 => $block[1]);
17326: }
17327: unset($cssblocks[$key]);
17328: }
17329: }
17330:
17331: $cssdata = array();
17332: foreach ($cssblocks as $block) {
17333: $selector = $block[0];
17334:
17335: $matches = array();
17336: $a = 0;
17337: $b = intval(preg_match_all('/[\#]/', $selector, $matches));
17338: $c = intval(preg_match_all('/[\[\.]/', $selector, $matches));
17339: $c += intval(preg_match_all('/[\:]link|visited|hover|active|focus|target|lang|enabled|disabled|checked|indeterminate|root|nth|first|last|only|empty|contains|not/i', $selector, $matches));
17340: $d = intval(preg_match_all('/[\>\+\~\s]{1}[a-zA-Z0-9\*]+/', ' '.$selector, $matches));
17341: $d += intval(preg_match_all('/[\:][\:]/', $selector, $matches));
17342: $specificity = $a.$b.$c.$d;
17343:
17344: $cssdata[$specificity.' '.$selector] = $block[1];
17345: }
17346:
17347: ksort($cssdata, SORT_STRING);
17348:
17349: return $cssdata;
17350: }
17351:
17352: 17353: 17354: 17355: 17356: 17357: 17358: 17359: 17360:
17361: protected function isValidCSSSelectorForTag($dom, $key, $selector) {
17362: $valid = false;
17363: $tag = $dom[$key]['value'];
17364: $class = array();
17365: if (isset($dom[$key]['attribute']['class']) AND !empty($dom[$key]['attribute']['class'])) {
17366: $class = explode(' ', strtolower($dom[$key]['attribute']['class']));
17367: }
17368: $id = '';
17369: if (isset($dom[$key]['attribute']['id']) AND !empty($dom[$key]['attribute']['id'])) {
17370: $id = strtolower($dom[$key]['attribute']['id']);
17371: }
17372: $selector = preg_replace('/([\>\+\~\s]{1})([\.]{1})([^\>\+\~\s]*)/si', '\\1*.\\3', $selector);
17373: $matches = array();
17374: if (preg_match_all('/([\>\+\~\s]{1})([a-zA-Z0-9\*]+)([^\>\+\~\s]*)/si', $selector, $matches, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE) > 0) {
17375: $parentop = array_pop($matches[1]);
17376: $operator = $parentop[0];
17377: $offset = $parentop[1];
17378: $lasttag = array_pop($matches[2]);
17379: $lasttag = strtolower(trim($lasttag[0]));
17380: if (($lasttag == '*') OR ($lasttag == $tag)) {
17381:
17382: $attrib = array_pop($matches[3]);
17383: $attrib = strtolower(trim($attrib[0]));
17384: if (!empty($attrib)) {
17385:
17386: switch ($attrib{0}) {
17387: case '.': {
17388: if (in_array(substr($attrib, 1), $class)) {
17389: $valid = true;
17390: }
17391: break;
17392: }
17393: case '#': {
17394: if (substr($attrib, 1) == $id) {
17395: $valid = true;
17396: }
17397: break;
17398: }
17399: case '[': {
17400: $attrmatch = array();
17401: if (preg_match('/\[([a-zA-Z0-9]*)[\s]*([\~\^\$\*\|\=]*)[\s]*["]?([^"\]]*)["]?\]/i', $attrib, $attrmatch) > 0) {
17402: $att = strtolower($attrmatch[1]);
17403: $val = $attrmatch[3];
17404: if (isset($dom[$key]['attribute'][$att])) {
17405: switch ($attrmatch[2]) {
17406: case '=': {
17407: if ($dom[$key]['attribute'][$att] == $val) {
17408: $valid = true;
17409: }
17410: break;
17411: }
17412: case '~=': {
17413: if (in_array($val, explode(' ', $dom[$key]['attribute'][$att]))) {
17414: $valid = true;
17415: }
17416: break;
17417: }
17418: case '^=': {
17419: if ($val == substr($dom[$key]['attribute'][$att], 0, strlen($val))) {
17420: $valid = true;
17421: }
17422: break;
17423: }
17424: case '$=': {
17425: if ($val == substr($dom[$key]['attribute'][$att], -strlen($val))) {
17426: $valid = true;
17427: }
17428: break;
17429: }
17430: case '*=': {
17431: if (strpos($dom[$key]['attribute'][$att], $val) !== false) {
17432: $valid = true;
17433: }
17434: break;
17435: }
17436: case '|=': {
17437: if ($dom[$key]['attribute'][$att] == $val) {
17438: $valid = true;
17439: } elseif (preg_match('/'.$val.'[\-]{1}/i', $dom[$key]['attribute'][$att]) > 0) {
17440: $valid = true;
17441: }
17442: break;
17443: }
17444: default: {
17445: $valid = true;
17446: }
17447: }
17448: }
17449: }
17450: break;
17451: }
17452: case ':': {
17453: if ($attrib{1} == ':') {
17454:
17455:
17456: } else {
17457:
17458:
17459: }
17460: break;
17461: }
17462: }
17463: } else {
17464: $valid = true;
17465: }
17466: if ($valid AND ($offset > 0)) {
17467: $valid = false;
17468:
17469: $selector = substr($selector, 0, $offset);
17470: switch ($operator) {
17471: case ' ': {
17472: while ($dom[$key]['parent'] > 0) {
17473: if ($this->isValidCSSSelectorForTag($dom, $dom[$key]['parent'], $selector)) {
17474: $valid = true;
17475: break;
17476: } else {
17477: $key = $dom[$key]['parent'];
17478: }
17479: }
17480: break;
17481: }
17482: case '>': {
17483: $valid = $this->isValidCSSSelectorForTag($dom, $dom[$key]['parent'], $selector);
17484: break;
17485: }
17486: case '+': {
17487: for ($i = ($key - 1); $i > $dom[$key]['parent']; --$i) {
17488: if ($dom[$i]['tag'] AND $dom[$i]['opening']) {
17489: $valid = $this->isValidCSSSelectorForTag($dom, $i, $selector);
17490: break;
17491: }
17492: }
17493: break;
17494: }
17495: case '~': {
17496: for ($i = ($key - 1); $i > $dom[$key]['parent']; --$i) {
17497: if ($dom[$i]['tag'] AND $dom[$i]['opening']) {
17498: if ($this->isValidCSSSelectorForTag($dom, $i, $selector)) {
17499: break;
17500: }
17501: }
17502: }
17503: break;
17504: }
17505: }
17506: }
17507: }
17508: }
17509: return $valid;
17510: }
17511:
17512: 17513: 17514: 17515: 17516: 17517: 17518: 17519: 17520:
17521: protected function getTagStyleFromCSS($dom, $key, $css) {
17522: $tagstyle = '';
17523:
17524: foreach($css as $selector => $style) {
17525:
17526: $selector = substr($selector, strpos($selector, ' '));
17527:
17528: if ($this->isValidCSSSelectorForTag($dom, $key, $selector)) {
17529:
17530: $tagstyle .= ';'.$style;
17531: }
17532: }
17533: if (isset($dom[$key]['attribute']['style'])) {
17534:
17535: $tagstyle .= ';'.$dom[$key]['attribute']['style'];
17536: }
17537:
17538: $tagstyle = preg_replace('/[;]+/', ';', $tagstyle);
17539: return $tagstyle;
17540: }
17541:
17542: 17543: 17544: 17545: 17546: 17547: 17548:
17549: protected function getCSSBorderWidth($width) {
17550: if ($width == 'thin') {
17551: $width = (2 / $this->k);
17552: } elseif ($width == 'medium') {
17553: $width = (4 / $this->k);
17554: } elseif ($width == 'thick') {
17555: $width = (6 / $this->k);
17556: } else {
17557: $width = $this->getHTMLUnitToUnits($width, 1, 'px', false);
17558: }
17559: return $width;
17560: }
17561:
17562: 17563: 17564: 17565: 17566: 17567: 17568:
17569: protected function getCSSBorderDashStyle($style) {
17570: switch (strtolower($style)) {
17571: case 'none':
17572: case 'hidden': {
17573: $dash = -1;
17574: break;
17575: }
17576: case 'dotted': {
17577: $dash = 1;
17578: break;
17579: }
17580: case 'dashed': {
17581: $dash = 3;
17582: break;
17583: }
17584: case 'double':
17585: case 'groove':
17586: case 'ridge':
17587: case 'inset':
17588: case 'outset':
17589: case 'solid':
17590: default: {
17591: $dash = 0;
17592: break;
17593: }
17594: }
17595: return $dash;
17596: }
17597:
17598: 17599: 17600: 17601: 17602: 17603: 17604:
17605: protected function getCSSBorderStyle($cssborder) {
17606: $bprop = preg_split('/[\s]+/', trim($cssborder));
17607: $border = array();
17608: switch (count($bprop)) {
17609: case 3: {
17610: $width = $bprop[0];
17611: $style = $bprop[1];
17612: $color = $bprop[2];
17613: break;
17614: }
17615: case 2: {
17616: $width = 'medium';
17617: $style = $bprop[0];
17618: $color = $bprop[1];
17619: break;
17620: }
17621: case 1: {
17622: $width = 'medium';
17623: $style = $bprop[0];
17624: $color = 'black';
17625: break;
17626: }
17627: default: {
17628: $width = 'medium';
17629: $style = 'solid';
17630: $color = 'black';
17631: break;
17632: }
17633: }
17634: if ($style == 'none') {
17635: return array();
17636: }
17637: $border['cap'] = 'square';
17638: $border['join'] = 'miter';
17639: $border['dash'] = $this->getCSSBorderDashStyle($style);
17640: if ($border['dash'] < 0) {
17641: return array();
17642: }
17643: $border['width'] = $this->getCSSBorderWidth($width);
17644: $border['color'] = $this->convertHTMLColorToDec($color);
17645: return $border;
17646: }
17647:
17648: 17649: 17650: 17651: 17652: 17653: 17654:
17655: public function getCSSPadding($csspadding, $width=0) {
17656: $padding = preg_split('/[\s]+/', trim($csspadding));
17657: $cell_padding = array();
17658: switch (count($padding)) {
17659: case 4: {
17660: $cell_padding['T'] = $padding[0];
17661: $cell_padding['R'] = $padding[1];
17662: $cell_padding['B'] = $padding[2];
17663: $cell_padding['L'] = $padding[3];
17664: break;
17665: }
17666: case 3: {
17667: $cell_padding['T'] = $padding[0];
17668: $cell_padding['R'] = $padding[1];
17669: $cell_padding['B'] = $padding[2];
17670: $cell_padding['L'] = $padding[1];
17671: break;
17672: }
17673: case 2: {
17674: $cell_padding['T'] = $padding[0];
17675: $cell_padding['R'] = $padding[1];
17676: $cell_padding['B'] = $padding[0];
17677: $cell_padding['L'] = $padding[1];
17678: break;
17679: }
17680: case 1: {
17681: $cell_padding['T'] = $padding[0];
17682: $cell_padding['R'] = $padding[0];
17683: $cell_padding['B'] = $padding[0];
17684: $cell_padding['L'] = $padding[0];
17685: break;
17686: }
17687: default: {
17688: return $this->cell_padding;
17689: }
17690: }
17691: if ($width == 0) {
17692: $width = $this->w - $this->lMargin - $this->rMargin;
17693: }
17694: $cell_padding['T'] = $this->getHTMLUnitToUnits($cell_padding['T'], $width, 'px', false);
17695: $cell_padding['R'] = $this->getHTMLUnitToUnits($cell_padding['R'], $width, 'px', false);
17696: $cell_padding['B'] = $this->getHTMLUnitToUnits($cell_padding['B'], $width, 'px', false);
17697: $cell_padding['L'] = $this->getHTMLUnitToUnits($cell_padding['L'], $width, 'px', false);
17698: return $cell_padding;
17699: }
17700:
17701: 17702: 17703: 17704: 17705: 17706: 17707:
17708: public function getCSSMargin($cssmargin, $width=0) {
17709: $margin = preg_split('/[\s]+/', trim($cssmargin));
17710: $cell_margin = array();
17711: switch (count($margin)) {
17712: case 4: {
17713: $cell_margin['T'] = $margin[0];
17714: $cell_margin['R'] = $margin[1];
17715: $cell_margin['B'] = $margin[2];
17716: $cell_margin['L'] = $margin[3];
17717: break;
17718: }
17719: case 3: {
17720: $cell_margin['T'] = $margin[0];
17721: $cell_margin['R'] = $margin[1];
17722: $cell_margin['B'] = $margin[2];
17723: $cell_margin['L'] = $margin[1];
17724: break;
17725: }
17726: case 2: {
17727: $cell_margin['T'] = $margin[0];
17728: $cell_margin['R'] = $margin[1];
17729: $cell_margin['B'] = $margin[0];
17730: $cell_margin['L'] = $margin[1];
17731: break;
17732: }
17733: case 1: {
17734: $cell_margin['T'] = $margin[0];
17735: $cell_margin['R'] = $margin[0];
17736: $cell_margin['B'] = $margin[0];
17737: $cell_margin['L'] = $margin[0];
17738: break;
17739: }
17740: default: {
17741: return $this->cell_margin;
17742: }
17743: }
17744: if ($width == 0) {
17745: $width = $this->w - $this->lMargin - $this->rMargin;
17746: }
17747: $cell_margin['T'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['T']), $width, 'px', false);
17748: $cell_margin['R'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['R']), $width, 'px', false);
17749: $cell_margin['B'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['B']), $width, 'px', false);
17750: $cell_margin['L'] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $cell_margin['L']), $width, 'px', false);
17751: return $cell_margin;
17752: }
17753:
17754: 17755: 17756: 17757: 17758: 17759: 17760: 17761:
17762: protected function getCSSFontSpacing($spacing, $parent=0) {
17763: $val = 0;
17764: $spacing = trim($spacing);
17765: switch ($spacing) {
17766: case 'normal': {
17767: $val = 0;
17768: break;
17769: }
17770: case 'inherit': {
17771: if ($parent == 'normal') {
17772: $val = 0;
17773: } else {
17774: $val = $parent;
17775: }
17776: break;
17777: }
17778: default: {
17779: $val = $this->getHTMLUnitToUnits($spacing, 0, 'px', false);
17780: }
17781: }
17782: return $val;
17783: }
17784:
17785: 17786: 17787: 17788: 17789: 17790: 17791: 17792:
17793: protected function getCSSFontStretching($stretch, $parent=100) {
17794: $val = 100;
17795: $stretch = trim($stretch);
17796: switch ($stretch) {
17797: case 'ultra-condensed': {
17798: $val = 40;
17799: break;
17800: }
17801: case 'extra-condensed': {
17802: $val = 55;
17803: break;
17804: }
17805: case 'condensed': {
17806: $val = 70;
17807: break;
17808: }
17809: case 'semi-condensed': {
17810: $val = 85;
17811: break;
17812: }
17813: case 'normal': {
17814: $val = 100;
17815: break;
17816: }
17817: case 'semi-expanded': {
17818: $val = 115;
17819: break;
17820: }
17821: case 'expanded': {
17822: $val = 130;
17823: break;
17824: }
17825: case 'extra-expanded': {
17826: $val = 145;
17827: break;
17828: }
17829: case 'ultra-expanded': {
17830: $val = 160;
17831: break;
17832: }
17833: case 'wider': {
17834: $val = $parent + 10;
17835: break;
17836: }
17837: case 'narrower': {
17838: $val = $parent - 10;
17839: break;
17840: }
17841: case 'inherit': {
17842: if ($parent == 'normal') {
17843: $val = 100;
17844: } else {
17845: $val = $parent;
17846: }
17847: break;
17848: }
17849: default: {
17850: $val = $this->getHTMLUnitToUnits($stretch, 100, '%', false);
17851: }
17852: }
17853: return $val;
17854: }
17855:
17856: 17857: 17858: 17859: 17860: 17861: 17862:
17863: protected function getHtmlDomArray($html) {
17864:
17865: $css = array();
17866:
17867: $matches = array();
17868: if (preg_match_all('/<cssarray>([^\<]*)<\/cssarray>/isU', $html, $matches) > 0) {
17869: if (isset($matches[1][0])) {
17870: $css = array_merge($css, unserialize($this->unhtmlentities($matches[1][0])));
17871: }
17872: $html = preg_replace('/<cssarray>(.*?)<\/cssarray>/isU', '', $html);
17873: }
17874:
17875: $matches = array();
17876: if (preg_match_all('/<link([^\>]*)>/isU', $html, $matches) > 0) {
17877: foreach ($matches[1] as $key => $link) {
17878: $type = array();
17879: if (preg_match('/type[\s]*=[\s]*"text\/css"/', $link, $type)) {
17880: $type = array();
17881: preg_match('/media[\s]*=[\s]*"([^"]*)"/', $link, $type);
17882:
17883:
17884: if (empty($type) OR (isset($type[1]) AND (($type[1] == 'all') OR ($type[1] == 'print')))) {
17885: $type = array();
17886: if (preg_match('/href[\s]*=[\s]*"([^"]*)"/', $link, $type) > 0) {
17887:
17888: $cssdata = file_get_contents(trim($type[1]));
17889: $css = array_merge($css, $this->extractCSSproperties($cssdata));
17890: }
17891: }
17892: }
17893: }
17894: }
17895:
17896: $matches = array();
17897: if (preg_match_all('/<style([^\>]*)>([^\<]*)<\/style>/isU', $html, $matches) > 0) {
17898: foreach ($matches[1] as $key => $media) {
17899: $type = array();
17900: preg_match('/media[\s]*=[\s]*"([^"]*)"/', $media, $type);
17901:
17902:
17903: if (empty($type) OR (isset($type[1]) AND (($type[1] == 'all') OR ($type[1] == 'print')))) {
17904: $cssdata = $matches[2][$key];
17905: $css = array_merge($css, $this->extractCSSproperties($cssdata));
17906: }
17907: }
17908: }
17909:
17910: $csstagarray = '<cssarray>'.htmlentities(serialize($css)).'</cssarray>';
17911:
17912: $html = preg_replace('/<head([^\>]*)>(.*?)<\/head>/siU', '', $html);
17913: $html = preg_replace('/<style([^\>]*)>([^\<]*)<\/style>/isU', '', $html);
17914:
17915: $blocktags = array('blockquote','br','dd','dl','div','dt','h1','h2','h3','h4','h5','h6','hr','li','ol','p','pre','ul','tcpdf','table','tr','td');
17916:
17917: $selfclosingtags = array('area','base','basefont','br','hr','input','img','link','meta');
17918:
17919: $html = strip_tags($html, '<marker/><a><b><blockquote><body><br><br/><dd><del><div><dl><dt><em><font><form><h1><h2><h3><h4><h5><h6><hr><hr/><i><img><input><label><li><ol><option><p><pre><s><select><small><span><strike><strong><sub><sup><table><tablehead><tcpdf><td><textarea><th><thead><tr><tt><u><ul>');
17920:
17921: $html = preg_replace('/<pre/', '<xre', $html);
17922: $html = preg_replace('/<(table|tr|td|th|tcpdf|blockquote|dd|div|dl|dt|form|h1|h2|h3|h4|h5|h6|br|hr|li|ol|ul|p)([^\>]*)>[\n\r\t]+/', '<\\1\\2>', $html);
17923: $html = preg_replace('@(\r\n|\r)@', "\n", $html);
17924: $repTable = array("\t" => ' ', "\0" => ' ', "\x0B" => ' ', "\\" => "\\\\");
17925: $html = strtr($html, $repTable);
17926: $offset = 0;
17927: while (($offset < strlen($html)) AND ($pos = strpos($html, '</pre>', $offset)) !== false) {
17928: $html_a = substr($html, 0, $offset);
17929: $html_b = substr($html, $offset, ($pos - $offset + 6));
17930: while (preg_match("'<xre([^\>]*)>(.*?)\n(.*?)</pre>'si", $html_b)) {
17931:
17932: $html_b = preg_replace("'<xre([^\>]*)>(.*?)\n(.*?)</pre>'si", "<xre\\1>\\2<br />\\3</pre>", $html_b);
17933: }
17934: while (preg_match("'<xre([^\>]*)>(.*?)".$this->re_space['p']."(.*?)</pre>'".$this->re_space['m'], $html_b)) {
17935:
17936: $html_b = preg_replace("'<xre([^\>]*)>(.*?)".$this->re_space['p']."(.*?)</pre>'".$this->re_space['m'], "<xre\\1>\\2 \\3</pre>", $html_b);
17937: }
17938: $html = $html_a.$html_b.substr($html, $pos + 6);
17939: $offset = strlen($html_a.$html_b);
17940: }
17941: $offset = 0;
17942: while (($offset < strlen($html)) AND ($pos = strpos($html, '</textarea>', $offset)) !== false) {
17943: $html_a = substr($html, 0, $offset);
17944: $html_b = substr($html, $offset, ($pos - $offset + 11));
17945: while (preg_match("'<textarea([^\>]*)>(.*?)\n(.*?)</textarea>'si", $html_b)) {
17946:
17947: $html_b = preg_replace("'<textarea([^\>]*)>(.*?)\n(.*?)</textarea>'si", "<textarea\\1>\\2<TBR>\\3</textarea>", $html_b);
17948: $html_b = preg_replace("'<textarea([^\>]*)>(.*?)[\"](.*?)</textarea>'si", "<textarea\\1>\\2''\\3</textarea>", $html_b);
17949: }
17950: $html = $html_a.$html_b.substr($html, $pos + 11);
17951: $offset = strlen($html_a.$html_b);
17952: }
17953: $html = preg_replace('/([\s]*)<option/si', '<option', $html);
17954: $html = preg_replace('/<\/option>([\s]*)/si', '</option>', $html);
17955: $offset = 0;
17956: while (($offset < strlen($html)) AND ($pos = strpos($html, '</option>', $offset)) !== false) {
17957: $html_a = substr($html, 0, $offset);
17958: $html_b = substr($html, $offset, ($pos - $offset + 9));
17959: while (preg_match("'<option([^\>]*)>(.*?)</option>'si", $html_b)) {
17960: $html_b = preg_replace("'<option([\s]+)value=\"([^\"]*)\"([^\>]*)>(.*?)</option>'si", "\\2#!TaB!#\\4#!NwL!#", $html_b);
17961: $html_b = preg_replace("'<option([^\>]*)>(.*?)</option>'si", "\\2#!NwL!#", $html_b);
17962: }
17963: $html = $html_a.$html_b.substr($html, $pos + 9);
17964: $offset = strlen($html_a.$html_b);
17965: }
17966: if (preg_match("'</select'si", $html)) {
17967: $html = preg_replace("'<select([^\>]*)>'si", "<select\\1 opt=\"", $html);
17968: $html = preg_replace("'#!NwL!#</select>'si", "\" />", $html);
17969: }
17970: $html = str_replace("\n", ' ', $html);
17971:
17972: $html = str_replace('<TBR>', "\n", $html);
17973:
17974: $html = preg_replace('/[\s]+<\/(table|tr|ul|ol|dl)>/', '</\\1>', $html);
17975: $html = preg_replace('/'.$this->re_space['p'].'+<\/(td|th|li|dt|dd)>/'.$this->re_space['m'], '</\\1>', $html);
17976: $html = preg_replace('/[\s]+<(tr|td|th|li|dt|dd)/', '<\\1', $html);
17977: $html = preg_replace('/'.$this->re_space['p'].'+<(ul|ol|dl|br)/'.$this->re_space['m'], '<\\1', $html);
17978: $html = preg_replace('/<\/(table|tr|td|th|blockquote|dd|dt|dl|div|dt|h1|h2|h3|h4|h5|h6|hr|li|ol|ul|p)>[\s]+</', '</\\1><', $html);
17979: $html = preg_replace('/<\/(td|th)>/', '<marker style="font-size:0"/></\\1>', $html);
17980: $html = preg_replace('/<\/table>([\s]*)<marker style="font-size:0"\/>/', '</table>', $html);
17981: $html = preg_replace('/'.$this->re_space['p'].'+<img/'.$this->re_space['m'], chr(32).'<img', $html);
17982: $html = preg_replace('/<img([^\>]*)>/xi', '<img\\1><span><marker style="font-size:0"/></span>', $html);
17983: $html = preg_replace('/<xre/', '<pre', $html);
17984: $html = preg_replace('/<textarea([^\>]*)>([^\<]*)<\/textarea>/xi', '<textarea\\1 value="\\2" />', $html);
17985: $html = preg_replace('/<li([^\>]*)><\/li>/', '<li\\1> </li>', $html);
17986: $html = preg_replace('/<li([^\>]*)>'.$this->re_space['p'].'*<img/'.$this->re_space['m'], '<li\\1><font size="1"> </font><img', $html);
17987: $html = preg_replace('/<([^\>\/]*)>[\s]/', '<\\1> ', $html);
17988: $html = preg_replace('/[\s]<\/([^\>]*)>/', ' </\\1>', $html);
17989: $html = preg_replace('/'.$this->re_space['p'].'+/'.$this->re_space['m'], chr(32), $html);
17990:
17991: $html = $this->stringTrim($html);
17992:
17993: $tagpattern = '/(<[^>]+>)/';
17994:
17995: $a = preg_split($tagpattern, $html, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
17996:
17997: $maxel = count($a);
17998: $elkey = 0;
17999: $key = 0;
18000:
18001: $dom = array();
18002: $dom[$key] = array();
18003:
18004:
18005: $dom[$key]['tag'] = false;
18006: $dom[$key]['block'] = false;
18007: $dom[$key]['value'] = '';
18008: $dom[$key]['parent'] = 0;
18009: $dom[$key]['fontname'] = $this->FontFamily;
18010: $dom[$key]['fontstyle'] = $this->FontStyle;
18011: $dom[$key]['fontsize'] = $this->FontSizePt;
18012: $dom[$key]['font-stretch'] = 100;
18013: $dom[$key]['letter-spacing'] = 0;
18014: $dom[$key]['stroke'] = $this->textstrokewidth;
18015: $dom[$key]['fill'] = (($this->textrendermode % 2) == 0);
18016: $dom[$key]['clip'] = ($this->textrendermode > 3);
18017: $dom[$key]['line-height'] = $this->cell_height_ratio;
18018: $dom[$key]['bgcolor'] = false;
18019: $dom[$key]['fgcolor'] = $this->fgcolor;
18020: $dom[$key]['strokecolor'] = $this->strokecolor;
18021: $dom[$key]['align'] = '';
18022: $dom[$key]['listtype'] = '';
18023: $dom[$key]['text-indent'] = 0;
18024: $dom[$key]['border'] = array();
18025: $dom[$key]['dir'] = $this->rtl?'rtl':'ltr';
18026: $thead = false;
18027: ++$key;
18028: $level = array();
18029: array_push($level, 0);
18030: while ($elkey < $maxel) {
18031: $dom[$key] = array();
18032: $element = $a[$elkey];
18033: $dom[$key]['elkey'] = $elkey;
18034: if (preg_match($tagpattern, $element)) {
18035:
18036: $element = substr($element, 1, -1);
18037:
18038: preg_match('/[\/]?([a-zA-Z0-9]*)/', $element, $tag);
18039: $tagname = strtolower($tag[1]);
18040:
18041: if ($tagname == 'thead') {
18042: if ($element{0} == '/') {
18043: $thead = false;
18044: } else {
18045: $thead = true;
18046: }
18047: ++$elkey;
18048: continue;
18049: }
18050: $dom[$key]['tag'] = true;
18051: $dom[$key]['value'] = $tagname;
18052: if (in_array($dom[$key]['value'], $blocktags)) {
18053: $dom[$key]['block'] = true;
18054: } else {
18055: $dom[$key]['block'] = false;
18056: }
18057: if ($element{0} == '/') {
18058:
18059: $dom[$key]['opening'] = false;
18060: $dom[$key]['parent'] = end($level);
18061: array_pop($level);
18062: $dom[$key]['fontname'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontname'];
18063: $dom[$key]['fontstyle'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontstyle'];
18064: $dom[$key]['fontsize'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fontsize'];
18065: $dom[$key]['font-stretch'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['font-stretch'];
18066: $dom[$key]['letter-spacing'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['letter-spacing'];
18067: $dom[$key]['stroke'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['stroke'];
18068: $dom[$key]['fill'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fill'];
18069: $dom[$key]['clip'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['clip'];
18070: $dom[$key]['line-height'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['line-height'];
18071: $dom[$key]['bgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['bgcolor'];
18072: $dom[$key]['fgcolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['fgcolor'];
18073: $dom[$key]['strokecolor'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['strokecolor'];
18074: $dom[$key]['align'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['align'];
18075: $dom[$key]['dir'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['dir'];
18076: if (isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype'])) {
18077: $dom[$key]['listtype'] = $dom[($dom[($dom[$key]['parent'])]['parent'])]['listtype'];
18078: }
18079:
18080: if (($dom[$key]['value'] == 'tr') AND (!isset($dom[($dom[($dom[$key]['parent'])]['parent'])]['cols']))) {
18081: $dom[($dom[($dom[$key]['parent'])]['parent'])]['cols'] = $dom[($dom[$key]['parent'])]['cols'];
18082: }
18083: if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) {
18084: $dom[($dom[$key]['parent'])]['content'] = $csstagarray;
18085: for ($i = ($dom[$key]['parent'] + 1); $i < $key; ++$i) {
18086: $dom[($dom[$key]['parent'])]['content'] .= $a[$dom[$i]['elkey']];
18087: }
18088: $key = $i;
18089: $parent_table = $dom[$dom[$dom[($dom[$key]['parent'])]['parent']]['parent']];
18090: $parent_padding = 0;
18091: $parent_spacing = 0;
18092: if (isset($parent_table['attribute']['cellpadding'])) {
18093: $parent_padding = $this->getHTMLUnitToUnits($parent_table['attribute']['cellpadding'], 1, 'px');
18094: }
18095: if (isset($parent_table['attribute']['cellspacing'])) {
18096: $parent_spacing = $this->getHTMLUnitToUnits($parent_table['attribute']['cellspacing'], 1, 'px');
18097: }
18098:
18099: $dom[($dom[$key]['parent'])]['content'] = str_replace('<table', '<table nested="true" pcellpadding="'.$parent_padding.'" pcellspacing="'.$parent_spacing.'"', $dom[($dom[$key]['parent'])]['content']);
18100:
18101: $dom[($dom[$key]['parent'])]['content'] = str_replace('<thead>', '', $dom[($dom[$key]['parent'])]['content']);
18102: $dom[($dom[$key]['parent'])]['content'] = str_replace('</thead>', '', $dom[($dom[$key]['parent'])]['content']);
18103: }
18104:
18105: if (($dom[$key]['value'] == 'tr') AND ($dom[($dom[$key]['parent'])]['thead'] === true)) {
18106: if ($this->empty_string($dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'])) {
18107: $dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] = $a[$dom[($dom[($dom[$key]['parent'])]['parent'])]['elkey']];
18108: }
18109: for ($i = $dom[$key]['parent']; $i <= $key; ++$i) {
18110: $dom[($dom[($dom[$key]['parent'])]['parent'])]['thead'] .= $a[$dom[$i]['elkey']];
18111: }
18112: if (!isset($dom[($dom[$key]['parent'])]['attribute'])) {
18113: $dom[($dom[$key]['parent'])]['attribute'] = array();
18114: }
18115:
18116: $dom[($dom[$key]['parent'])]['attribute']['nobr'] = 'true';
18117: }
18118: if (($dom[$key]['value'] == 'table') AND (!$this->empty_string($dom[($dom[$key]['parent'])]['thead']))) {
18119:
18120: $dom[($dom[$key]['parent'])]['thead'] = str_replace(' nobr="true"', '', $dom[($dom[$key]['parent'])]['thead']);
18121: $dom[($dom[$key]['parent'])]['thead'] .= '</tablehead>';
18122: }
18123: } else {
18124:
18125: $dom[$key]['opening'] = true;
18126: $dom[$key]['parent'] = end($level);
18127: if ((substr($element, -1, 1) == '/') OR (in_array($dom[$key]['value'], $selfclosingtags))) {
18128:
18129: $dom[$key]['self'] = true;
18130: } else {
18131:
18132: array_push($level, $key);
18133: $dom[$key]['self'] = false;
18134: }
18135:
18136: $parentkey = 0;
18137: if ($key > 0) {
18138: $parentkey = $dom[$key]['parent'];
18139: $dom[$key]['fontname'] = $dom[$parentkey]['fontname'];
18140: $dom[$key]['fontstyle'] = $dom[$parentkey]['fontstyle'];
18141: $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'];
18142: $dom[$key]['font-stretch'] = $dom[$parentkey]['font-stretch'];
18143: $dom[$key]['letter-spacing'] = $dom[$parentkey]['letter-spacing'];
18144: $dom[$key]['stroke'] = $dom[$parentkey]['stroke'];
18145: $dom[$key]['fill'] = $dom[$parentkey]['fill'];
18146: $dom[$key]['clip'] = $dom[$parentkey]['clip'];
18147: $dom[$key]['line-height'] = $dom[$parentkey]['line-height'];
18148: $dom[$key]['bgcolor'] = $dom[$parentkey]['bgcolor'];
18149: $dom[$key]['fgcolor'] = $dom[$parentkey]['fgcolor'];
18150: $dom[$key]['strokecolor'] = $dom[$parentkey]['strokecolor'];
18151: $dom[$key]['align'] = $dom[$parentkey]['align'];
18152: $dom[$key]['listtype'] = $dom[$parentkey]['listtype'];
18153: $dom[$key]['text-indent'] = $dom[$parentkey]['text-indent'];
18154: $dom[$key]['border'] = array();
18155: $dom[$key]['dir'] = $dom[$parentkey]['dir'];
18156: }
18157:
18158: preg_match_all('/([^=\s]*)[\s]*=[\s]*"([^"]*)"/', $element, $attr_array, PREG_PATTERN_ORDER);
18159: $dom[$key]['attribute'] = array();
18160: while (list($id, $name) = each($attr_array[1])) {
18161: $dom[$key]['attribute'][strtolower($name)] = $attr_array[2][$id];
18162: }
18163: if (!empty($css)) {
18164:
18165: $dom[$key]['attribute']['style'] = $this->getTagStyleFromCSS($dom, $key, $css);
18166: }
18167:
18168: if (isset($dom[$key]['attribute']['style']) AND !empty($dom[$key]['attribute']['style'])) {
18169:
18170: preg_match_all('/([^;:\s]*):([^;]*)/', $dom[$key]['attribute']['style'], $style_array, PREG_PATTERN_ORDER);
18171: $dom[$key]['style'] = array();
18172: while (list($id, $name) = each($style_array[1])) {
18173:
18174: $dom[$key]['style'][strtolower($name)] = trim($style_array[2][$id]);
18175: }
18176:
18177:
18178: if (isset($dom[$key]['style']['direction'])) {
18179: $dom[$key]['dir'] = $dom[$key]['style']['direction'];
18180: }
18181:
18182: if (isset($dom[$key]['style']['font-family'])) {
18183: $dom[$key]['fontname'] = $this->getFontFamilyName($dom[$key]['style']['font-family']);
18184: }
18185:
18186: if (isset($dom[$key]['style']['list-style-type'])) {
18187: $dom[$key]['listtype'] = trim(strtolower($dom[$key]['style']['list-style-type']));
18188: if ($dom[$key]['listtype'] == 'inherit') {
18189: $dom[$key]['listtype'] = $dom[$parentkey]['listtype'];
18190: }
18191: }
18192:
18193: if (isset($dom[$key]['style']['text-indent'])) {
18194: $dom[$key]['text-indent'] = $this->getHTMLUnitToUnits($dom[$key]['style']['text-indent']);
18195: if ($dom[$key]['text-indent'] == 'inherit') {
18196: $dom[$key]['text-indent'] = $dom[$parentkey]['text-indent'];
18197: }
18198: }
18199:
18200: if (isset($dom[$key]['style']['font-size'])) {
18201: $fsize = trim($dom[$key]['style']['font-size']);
18202: switch ($fsize) {
18203:
18204: case 'xx-small': {
18205: $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 4;
18206: break;
18207: }
18208: case 'x-small': {
18209: $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 3;
18210: break;
18211: }
18212: case 'small': {
18213: $dom[$key]['fontsize'] = $dom[0]['fontsize'] - 2;
18214: break;
18215: }
18216: case 'medium': {
18217: $dom[$key]['fontsize'] = $dom[0]['fontsize'];
18218: break;
18219: }
18220: case 'large': {
18221: $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 2;
18222: break;
18223: }
18224: case 'x-large': {
18225: $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 4;
18226: break;
18227: }
18228: case 'xx-large': {
18229: $dom[$key]['fontsize'] = $dom[0]['fontsize'] + 6;
18230: break;
18231: }
18232:
18233: case 'smaller': {
18234: $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'] - 3;
18235: break;
18236: }
18237: case 'larger': {
18238: $dom[$key]['fontsize'] = $dom[$parentkey]['fontsize'] + 3;
18239: break;
18240: }
18241: default: {
18242: $dom[$key]['fontsize'] = $this->getHTMLUnitToUnits($fsize, $dom[$parentkey]['fontsize'], 'pt', true);
18243: }
18244: }
18245: }
18246:
18247: if (isset($dom[$key]['style']['font-stretch'])) {
18248: $dom[$key]['font-stretch'] = $this->getCSSFontStretching($dom[$key]['style']['font-stretch'], $dom[$parentkey]['font-stretch']);
18249: }
18250:
18251: if (isset($dom[$key]['style']['letter-spacing'])) {
18252: $dom[$key]['letter-spacing'] = $this->getCSSFontSpacing($dom[$key]['style']['letter-spacing'], $dom[$parentkey]['letter-spacing']);
18253: }
18254:
18255: if (isset($dom[$key]['style']['line-height'])) {
18256: $lineheight = trim($dom[$key]['style']['line-height']);
18257: switch ($lineheight) {
18258:
18259: case 'normal': {
18260: $dom[$key]['line-height'] = $dom[0]['line-height'];
18261: break;
18262: }
18263: default: {
18264: if (is_numeric($lineheight)) {
18265: $lineheight = $lineheight * 100;
18266: }
18267: $dom[$key]['line-height'] = $this->getHTMLUnitToUnits($lineheight, 1, '%', true);
18268: }
18269: }
18270: }
18271:
18272: if (isset($dom[$key]['style']['font-weight']) AND (strtolower($dom[$key]['style']['font-weight']{0}) == 'b')) {
18273: $dom[$key]['fontstyle'] .= 'B';
18274: }
18275: if (isset($dom[$key]['style']['font-style']) AND (strtolower($dom[$key]['style']['font-style']{0}) == 'i')) {
18276: $dom[$key]['fontstyle'] .= 'I';
18277: }
18278:
18279: if (isset($dom[$key]['style']['color']) AND (!$this->empty_string($dom[$key]['style']['color']))) {
18280: $dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['style']['color']);
18281: } elseif ($dom[$key]['value'] == 'a') {
18282: $dom[$key]['fgcolor'] = $this->htmlLinkColorArray;
18283: }
18284:
18285: if (isset($dom[$key]['style']['background-color']) AND (!$this->empty_string($dom[$key]['style']['background-color']))) {
18286: $dom[$key]['bgcolor'] = $this->convertHTMLColorToDec($dom[$key]['style']['background-color']);
18287: }
18288:
18289: if (isset($dom[$key]['style']['text-decoration'])) {
18290: $decors = explode(' ', strtolower($dom[$key]['style']['text-decoration']));
18291: foreach ($decors as $dec) {
18292: $dec = trim($dec);
18293: if (!$this->empty_string($dec)) {
18294: if ($dec{0} == 'u') {
18295:
18296: $dom[$key]['fontstyle'] .= 'U';
18297: } elseif ($dec{0} == 'l') {
18298:
18299: $dom[$key]['fontstyle'] .= 'D';
18300: } elseif ($dec{0} == 'o') {
18301:
18302: $dom[$key]['fontstyle'] .= 'O';
18303: }
18304: }
18305: }
18306: } elseif ($dom[$key]['value'] == 'a') {
18307: $dom[$key]['fontstyle'] = $this->htmlLinkFontStyle;
18308: }
18309:
18310: if (isset($dom[$key]['style']['width'])) {
18311: $dom[$key]['width'] = $dom[$key]['style']['width'];
18312: }
18313:
18314: if (isset($dom[$key]['style']['height'])) {
18315: $dom[$key]['height'] = $dom[$key]['style']['height'];
18316: }
18317:
18318: if (isset($dom[$key]['style']['text-align'])) {
18319: $dom[$key]['align'] = strtoupper($dom[$key]['style']['text-align']{0});
18320: }
18321:
18322: if (isset($dom[$key]['style']['border'])) {
18323: $borderstyle = $this->getCSSBorderStyle($dom[$key]['style']['border']);
18324: if (!empty($borderstyle)) {
18325: $dom[$key]['border']['LTRB'] = $borderstyle;
18326: }
18327: }
18328: if (isset($dom[$key]['style']['border-color'])) {
18329: $brd_colors = preg_split('/[\s]+/', trim($dom[$key]['style']['border-color']));
18330: if (isset($brd_colors[3])) {
18331: $dom[$key]['border']['L']['color'] = $this->convertHTMLColorToDec($brd_colors[3]);
18332: }
18333: if (isset($brd_colors[1])) {
18334: $dom[$key]['border']['R']['color'] = $this->convertHTMLColorToDec($brd_colors[1]);
18335: }
18336: if (isset($brd_colors[0])) {
18337: $dom[$key]['border']['T']['color'] = $this->convertHTMLColorToDec($brd_colors[0]);
18338: }
18339: if (isset($brd_colors[2])) {
18340: $dom[$key]['border']['B']['color'] = $this->convertHTMLColorToDec($brd_colors[2]);
18341: }
18342: }
18343: if (isset($dom[$key]['style']['border-width'])) {
18344: $brd_widths = preg_split('/[\s]+/', trim($dom[$key]['style']['border-width']));
18345: if (isset($brd_widths[3])) {
18346: $dom[$key]['border']['L']['width'] = $this->getCSSBorderWidth($brd_widths[3]);
18347: }
18348: if (isset($brd_widths[1])) {
18349: $dom[$key]['border']['R']['width'] = $this->getCSSBorderWidth($brd_widths[1]);
18350: }
18351: if (isset($brd_widths[0])) {
18352: $dom[$key]['border']['T']['width'] = $this->getCSSBorderWidth($brd_widths[0]);
18353: }
18354: if (isset($brd_widths[2])) {
18355: $dom[$key]['border']['B']['width'] = $this->getCSSBorderWidth($brd_widths[2]);
18356: }
18357: }
18358: if (isset($dom[$key]['style']['border-style'])) {
18359: $brd_styles = preg_split('/[\s]+/', trim($dom[$key]['style']['border-style']));
18360: if (isset($brd_styles[3])) {
18361: $dom[$key]['border']['L']['cap'] = 'square';
18362: $dom[$key]['border']['L']['join'] = 'miter';
18363: $dom[$key]['border']['L']['dash'] = $this->getCSSBorderDashStyle($brd_styles[3]);
18364: if ($dom[$key]['border']['L']['dash'] < 0) {
18365: $dom[$key]['border']['L'] = array();
18366: }
18367: }
18368: if (isset($brd_styles[1])) {
18369: $dom[$key]['border']['R']['cap'] = 'square';
18370: $dom[$key]['border']['R']['join'] = 'miter';
18371: $dom[$key]['border']['R']['dash'] = $this->getCSSBorderDashStyle($brd_styles[1]);
18372: if ($dom[$key]['border']['R']['dash'] < 0) {
18373: $dom[$key]['border']['R'] = array();
18374: }
18375: }
18376: if (isset($brd_styles[0])) {
18377: $dom[$key]['border']['T']['cap'] = 'square';
18378: $dom[$key]['border']['T']['join'] = 'miter';
18379: $dom[$key]['border']['T']['dash'] = $this->getCSSBorderDashStyle($brd_styles[0]);
18380: if ($dom[$key]['border']['T']['dash'] < 0) {
18381: $dom[$key]['border']['T'] = array();
18382: }
18383: }
18384: if (isset($brd_styles[2])) {
18385: $dom[$key]['border']['B']['cap'] = 'square';
18386: $dom[$key]['border']['B']['join'] = 'miter';
18387: $dom[$key]['border']['B']['dash'] = $this->getCSSBorderDashStyle($brd_styles[2]);
18388: if ($dom[$key]['border']['B']['dash'] < 0) {
18389: $dom[$key]['border']['B'] = array();
18390: }
18391: }
18392: }
18393: $cellside = array('L' => 'left', 'R' => 'right', 'T' => 'top', 'B' => 'bottom');
18394: foreach ($cellside as $bsk => $bsv) {
18395: if (isset($dom[$key]['style']['border-'.$bsv])) {
18396: $borderstyle = $this->getCSSBorderStyle($dom[$key]['style']['border-'.$bsv]);
18397: if (!empty($borderstyle)) {
18398: $dom[$key]['border'][$bsk] = $borderstyle;
18399: }
18400: }
18401: if (isset($dom[$key]['style']['border-'.$bsv.'-color'])) {
18402: $dom[$key]['border'][$bsk]['color'] = $this->convertHTMLColorToDec($dom[$key]['style']['border-'.$bsv.'-color']);
18403: }
18404: if (isset($dom[$key]['style']['border-'.$bsv.'-width'])) {
18405: $dom[$key]['border'][$bsk]['width'] = $this->getCSSBorderWidth($dom[$key]['style']['border-'.$bsv.'-width']);
18406: }
18407: if (isset($dom[$key]['style']['border-'.$bsv.'-style'])) {
18408: $dom[$key]['border'][$bsk]['dash'] = $this->getCSSBorderDashStyle($dom[$key]['style']['border-'.$bsv.'-style']);
18409: if ($dom[$key]['border'][$bsk]['dash'] < 0) {
18410: $dom[$key]['border'][$bsk] = array();
18411: }
18412: }
18413: }
18414:
18415: if (isset($dom[$key]['style']['padding'])) {
18416: $dom[$key]['padding'] = $this->getCSSPadding($dom[$key]['style']['padding']);
18417: } else {
18418: $dom[$key]['padding'] = $this->cell_padding;
18419: }
18420: foreach ($cellside as $psk => $psv) {
18421: if (isset($dom[$key]['style']['padding-'.$psv])) {
18422: $dom[$key]['padding'][$psk] = $this->getHTMLUnitToUnits($dom[$key]['style']['padding-'.$psv], 0, 'px', false);
18423: }
18424: }
18425:
18426: if (isset($dom[$key]['style']['margin'])) {
18427: $dom[$key]['margin'] = $this->getCSSMargin($dom[$key]['style']['margin']);
18428: } else {
18429: $dom[$key]['margin'] = $this->cell_margin;
18430: }
18431: foreach ($cellside as $psk => $psv) {
18432: if (isset($dom[$key]['style']['margin-'.$psv])) {
18433: $dom[$key]['margin'][$psk] = $this->getHTMLUnitToUnits(str_replace('auto', '0', $dom[$key]['style']['margin-'.$psv]), 0, 'px', false);
18434: }
18435: }
18436:
18437: if (isset($dom[$key]['style']['page-break-inside']) AND ($dom[$key]['style']['page-break-inside'] == 'avoid')) {
18438: $dom[$key]['attribute']['nobr'] = 'true';
18439: }
18440:
18441: if (isset($dom[$key]['style']['page-break-before'])) {
18442: if ($dom[$key]['style']['page-break-before'] == 'always') {
18443: $dom[$key]['attribute']['pagebreak'] = 'true';
18444: } elseif ($dom[$key]['style']['page-break-before'] == 'left') {
18445: $dom[$key]['attribute']['pagebreak'] = 'left';
18446: } elseif ($dom[$key]['style']['page-break-before'] == 'right') {
18447: $dom[$key]['attribute']['pagebreak'] = 'right';
18448: }
18449: }
18450:
18451: if (isset($dom[$key]['style']['page-break-after'])) {
18452: if ($dom[$key]['style']['page-break-after'] == 'always') {
18453: $dom[$key]['attribute']['pagebreakafter'] = 'true';
18454: } elseif ($dom[$key]['style']['page-break-after'] == 'left') {
18455: $dom[$key]['attribute']['pagebreakafter'] = 'left';
18456: } elseif ($dom[$key]['style']['page-break-after'] == 'right') {
18457: $dom[$key]['attribute']['pagebreakafter'] = 'right';
18458: }
18459: }
18460: }
18461: if (isset($dom[$key]['attribute']['border']) AND ($dom[$key]['attribute']['border'] != 0)) {
18462: $borderstyle = $this->getCSSBorderStyle($dom[$key]['attribute']['border'].' solid black');
18463: if (!empty($borderstyle)) {
18464: $dom[$key]['border']['LTRB'] = $borderstyle;
18465: }
18466: }
18467:
18468: if ($dom[$key]['value'] == 'font') {
18469:
18470: if (isset($dom[$key]['attribute']['face'])) {
18471: $dom[$key]['fontname'] = $this->getFontFamilyName($dom[$key]['attribute']['face']);
18472: }
18473:
18474: if (isset($dom[$key]['attribute']['size'])) {
18475: if ($key > 0) {
18476: if ($dom[$key]['attribute']['size']{0} == '+') {
18477: $dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] + intval(substr($dom[$key]['attribute']['size'], 1));
18478: } elseif ($dom[$key]['attribute']['size']{0} == '-') {
18479: $dom[$key]['fontsize'] = $dom[($dom[$key]['parent'])]['fontsize'] - intval(substr($dom[$key]['attribute']['size'], 1));
18480: } else {
18481: $dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']);
18482: }
18483: } else {
18484: $dom[$key]['fontsize'] = intval($dom[$key]['attribute']['size']);
18485: }
18486: }
18487: }
18488:
18489: if ((($dom[$key]['value'] == 'ul') OR ($dom[$key]['value'] == 'ol') OR ($dom[$key]['value'] == 'dl'))
18490: AND (!isset($dom[$key]['align']) OR $this->empty_string($dom[$key]['align']) OR ($dom[$key]['align'] != 'J'))) {
18491: if ($this->rtl) {
18492: $dom[$key]['align'] = 'R';
18493: } else {
18494: $dom[$key]['align'] = 'L';
18495: }
18496: }
18497: if (($dom[$key]['value'] == 'small') OR ($dom[$key]['value'] == 'sup') OR ($dom[$key]['value'] == 'sub')) {
18498: if (!isset($dom[$key]['attribute']['size']) AND !isset($dom[$key]['style']['font-size'])) {
18499: $dom[$key]['fontsize'] = $dom[$key]['fontsize'] * K_SMALL_RATIO;
18500: }
18501: }
18502: if (($dom[$key]['value'] == 'strong') OR ($dom[$key]['value'] == 'b')) {
18503: $dom[$key]['fontstyle'] .= 'B';
18504: }
18505: if (($dom[$key]['value'] == 'em') OR ($dom[$key]['value'] == 'i')) {
18506: $dom[$key]['fontstyle'] .= 'I';
18507: }
18508: if ($dom[$key]['value'] == 'u') {
18509: $dom[$key]['fontstyle'] .= 'U';
18510: }
18511: if (($dom[$key]['value'] == 'del') OR ($dom[$key]['value'] == 's') OR ($dom[$key]['value'] == 'strike')) {
18512: $dom[$key]['fontstyle'] .= 'D';
18513: }
18514: if (!isset($dom[$key]['style']['text-decoration']) AND ($dom[$key]['value'] == 'a')) {
18515: $dom[$key]['fontstyle'] = $this->htmlLinkFontStyle;
18516: }
18517: if (($dom[$key]['value'] == 'pre') OR ($dom[$key]['value'] == 'tt')) {
18518: $dom[$key]['fontname'] = $this->default_monospaced_font;
18519: }
18520: if (($dom[$key]['value']{0} == 'h') AND (intval($dom[$key]['value']{1}) > 0) AND (intval($dom[$key]['value']{1}) < 7)) {
18521:
18522: if (!isset($dom[$key]['attribute']['size']) AND !isset($dom[$key]['style']['font-size'])) {
18523: $headsize = (4 - intval($dom[$key]['value']{1})) * 2;
18524: $dom[$key]['fontsize'] = $dom[0]['fontsize'] + $headsize;
18525: }
18526: if (!isset($dom[$key]['style']['font-weight'])) {
18527: $dom[$key]['fontstyle'] .= 'B';
18528: }
18529: }
18530: if (($dom[$key]['value'] == 'table')) {
18531: $dom[$key]['rows'] = 0;
18532: $dom[$key]['trids'] = array();
18533: $dom[$key]['thead'] = '';
18534: }
18535: if (($dom[$key]['value'] == 'tr')) {
18536: $dom[$key]['cols'] = 0;
18537: if ($thead) {
18538: $dom[$key]['thead'] = true;
18539:
18540: } else {
18541: $dom[$key]['thead'] = false;
18542:
18543: ++$dom[($dom[$key]['parent'])]['rows'];
18544:
18545: array_push($dom[($dom[$key]['parent'])]['trids'], $key);
18546: }
18547: }
18548: if (($dom[$key]['value'] == 'th') OR ($dom[$key]['value'] == 'td')) {
18549: if (isset($dom[$key]['attribute']['colspan'])) {
18550: $colspan = intval($dom[$key]['attribute']['colspan']);
18551: } else {
18552: $colspan = 1;
18553: }
18554: $dom[$key]['attribute']['colspan'] = $colspan;
18555: $dom[($dom[$key]['parent'])]['cols'] += $colspan;
18556: }
18557:
18558: if (isset($dom[$key]['attribute']['dir'])) {
18559: $dom[$key]['dir'] = $dom[$key]['attribute']['dir'];
18560: }
18561:
18562: if (isset($dom[$key]['attribute']['color']) AND (!$this->empty_string($dom[$key]['attribute']['color']))) {
18563: $dom[$key]['fgcolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['color']);
18564: } elseif (!isset($dom[$key]['style']['color']) AND ($dom[$key]['value'] == 'a')) {
18565: $dom[$key]['fgcolor'] = $this->htmlLinkColorArray;
18566: }
18567:
18568: if (isset($dom[$key]['attribute']['bgcolor']) AND (!$this->empty_string($dom[$key]['attribute']['bgcolor']))) {
18569: $dom[$key]['bgcolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['bgcolor']);
18570: }
18571:
18572: if (isset($dom[$key]['attribute']['strokecolor']) AND (!$this->empty_string($dom[$key]['attribute']['strokecolor']))) {
18573: $dom[$key]['strokecolor'] = $this->convertHTMLColorToDec($dom[$key]['attribute']['strokecolor']);
18574: }
18575:
18576: if (isset($dom[$key]['attribute']['width'])) {
18577: $dom[$key]['width'] = $dom[$key]['attribute']['width'];
18578: }
18579:
18580: if (isset($dom[$key]['attribute']['height'])) {
18581: $dom[$key]['height'] = $dom[$key]['attribute']['height'];
18582: }
18583:
18584: if (isset($dom[$key]['attribute']['align']) AND (!$this->empty_string($dom[$key]['attribute']['align'])) AND ($dom[$key]['value'] !== 'img')) {
18585: $dom[$key]['align'] = strtoupper($dom[$key]['attribute']['align']{0});
18586: }
18587:
18588: if (isset($dom[$key]['attribute']['stroke'])) {
18589:
18590: $dom[$key]['stroke'] = $this->getHTMLUnitToUnits($dom[$key]['attribute']['stroke'], $dom[$key]['fontsize'], 'pt', true);
18591: }
18592: if (isset($dom[$key]['attribute']['fill'])) {
18593:
18594: if ($dom[$key]['attribute']['fill'] == 'true') {
18595: $dom[$key]['fill'] = true;
18596: } else {
18597: $dom[$key]['fill'] = false;
18598: }
18599: }
18600: if (isset($dom[$key]['attribute']['clip'])) {
18601:
18602: if ($dom[$key]['attribute']['clip'] == 'true') {
18603: $dom[$key]['clip'] = true;
18604: } else {
18605: $dom[$key]['clip'] = false;
18606: }
18607: }
18608: }
18609: } else {
18610:
18611: $dom[$key]['tag'] = false;
18612: $dom[$key]['block'] = false;
18613: $element = str_replace('$nbsp;', $this->unichr(160), $element);
18614: $dom[$key]['value'] = stripslashes($this->unhtmlentities($element));
18615: $dom[$key]['parent'] = end($level);
18616: }
18617: ++$elkey;
18618: ++$key;
18619: }
18620: return $dom;
18621: }
18622:
18623: 18624: 18625: 18626: 18627: 18628: 18629:
18630: protected function getSpaceString() {
18631: $spacestr = chr(32);
18632: if ($this->isUnicodeFont()) {
18633: $spacestr = chr(0).chr(32);
18634: }
18635: return $spacestr;
18636: }
18637:
18638: 18639: 18640: 18641: 18642: 18643: 18644: 18645: 18646: 18647: 18648: 18649: 18650: 18651: 18652: 18653: 18654: 18655: 18656: 18657:
18658: public function writeHTMLCell($w, $h, $x, $y, $html='', $border=0, $ln=0, $fill=false, $reseth=true, $align='', $autopadding=true) {
18659: return $this->MultiCell($w, $h, $html, $border, $align, $fill, $ln, $x, $y, $reseth, 0, true, $autopadding, 0);
18660: }
18661:
18662: 18663: 18664: 18665: 18666: 18667: 18668: 18669: 18670: 18671: 18672: 18673:
18674: public function writeHTML($html, $ln=true, $fill=false, $reseth=false, $cell=false, $align='') {
18675: $gvars = $this->getGraphicVars();
18676:
18677: $prev_cell_margin = $this->cell_margin;
18678: $prev_cell_padding = $this->cell_padding;
18679: $prevPage = $this->page;
18680: $prevlMargin = $this->lMargin;
18681: $prevrMargin = $this->rMargin;
18682: $curfontname = $this->FontFamily;
18683: $curfontstyle = $this->FontStyle;
18684: $curfontsize = $this->FontSizePt;
18685: $curfontascent = $this->getFontAscent($curfontname, $curfontstyle, $curfontsize);
18686: $curfontdescent = $this->getFontDescent($curfontname, $curfontstyle, $curfontsize);
18687: $curfontstretcing = $this->font_stretching;
18688: $curfontkerning = $this->font_spacing;
18689: $this->newline = true;
18690: $newline = true;
18691: $startlinepage = $this->page;
18692: $minstartliney = $this->y;
18693: $maxbottomliney = 0;
18694: $startlinex = $this->x;
18695: $startliney = $this->y;
18696: $yshift = 0;
18697: $loop = 0;
18698: $curpos = 0;
18699: $this_method_vars = array();
18700: $undo = false;
18701: $fontaligned = false;
18702: $reverse_dir = false;
18703: $this->premode = false;
18704: if ($this->inxobj) {
18705:
18706: $pask = count($this->xobjects[$this->xobjid]['annotations']);
18707: } elseif (isset($this->PageAnnots[$this->page])) {
18708: $pask = count($this->PageAnnots[$this->page]);
18709: } else {
18710: $pask = 0;
18711: }
18712: if ($this->inxobj) {
18713:
18714: $startlinepos = strlen($this->xobjects[$this->xobjid]['outdata']);
18715: } elseif (!$this->InFooter) {
18716: if (isset($this->footerlen[$this->page])) {
18717: $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
18718: } else {
18719: $this->footerpos[$this->page] = $this->pagelen[$this->page];
18720: }
18721: $startlinepos = $this->footerpos[$this->page];
18722: } else {
18723:
18724: $startlinepos = $this->pagelen[$this->page];
18725: }
18726: $lalign = $align;
18727: $plalign = $align;
18728: if ($this->rtl) {
18729: $w = $this->x - $this->lMargin;
18730: } else {
18731: $w = $this->w - $this->rMargin - $this->x;
18732: }
18733: $w -= ($this->cell_padding['L'] + $this->cell_padding['R']);
18734: if ($cell) {
18735: if ($this->rtl) {
18736: $this->x -= $this->cell_padding['R'];
18737: $this->lMargin += $this->cell_padding['R'];
18738: } else {
18739: $this->x += $this->cell_padding['L'];
18740: $this->rMargin += $this->cell_padding['L'];
18741: }
18742: }
18743: if ($this->customlistindent >= 0) {
18744: $this->listindent = $this->customlistindent;
18745: } else {
18746: $this->listindent = $this->GetStringWidth('0000');
18747: }
18748: $this->listindentlevel = 0;
18749:
18750: $prev_cell_height_ratio = $this->cell_height_ratio;
18751: $prev_listnum = $this->listnum;
18752: $prev_listordered = $this->listordered;
18753: $prev_listcount = $this->listcount;
18754: $prev_lispacer = $this->lispacer;
18755: $this->listnum = 0;
18756: $this->listordered = array();
18757: $this->listcount = array();
18758: $this->lispacer = '';
18759: if (($this->empty_string($this->lasth)) OR ($reseth)) {
18760:
18761: $this->resetLastH();
18762: }
18763: $dom = $this->getHtmlDomArray($html);
18764: $maxel = count($dom);
18765: $key = 0;
18766: while ($key < $maxel) {
18767: if ($dom[$key]['tag'] AND isset($dom[$key]['attribute']['pagebreak'])) {
18768:
18769: if (($dom[$key]['attribute']['pagebreak'] == 'true') OR ($dom[$key]['attribute']['pagebreak'] == 'left') OR ($dom[$key]['attribute']['pagebreak'] == 'right')) {
18770:
18771: $this->checkPageBreak($this->PageBreakTrigger + 1);
18772: }
18773: if ((($dom[$key]['attribute']['pagebreak'] == 'left') AND (((!$this->rtl) AND (($this->page % 2) == 0)) OR (($this->rtl) AND (($this->page % 2) != 0))))
18774: OR (($dom[$key]['attribute']['pagebreak'] == 'right') AND (((!$this->rtl) AND (($this->page % 2) != 0)) OR (($this->rtl) AND (($this->page % 2) == 0))))) {
18775:
18776: $this->checkPageBreak($this->PageBreakTrigger + 1);
18777: }
18778: }
18779: if ($dom[$key]['tag'] AND $dom[$key]['opening'] AND isset($dom[$key]['attribute']['nobr']) AND ($dom[$key]['attribute']['nobr'] == 'true')) {
18780: if (isset($dom[($dom[$key]['parent'])]['attribute']['nobr']) AND ($dom[($dom[$key]['parent'])]['attribute']['nobr'] == 'true')) {
18781: $dom[$key]['attribute']['nobr'] = false;
18782: } else {
18783:
18784: $this->startTransaction();
18785:
18786: $this_method_vars['html'] = $html;
18787: $this_method_vars['ln'] = $ln;
18788: $this_method_vars['fill'] = $fill;
18789: $this_method_vars['reseth'] = $reseth;
18790: $this_method_vars['cell'] = $cell;
18791: $this_method_vars['align'] = $align;
18792: $this_method_vars['gvars'] = $gvars;
18793: $this_method_vars['prevPage'] = $prevPage;
18794: $this_method_vars['prev_cell_margin'] = $prev_cell_margin;
18795: $this_method_vars['prev_cell_padding'] = $prev_cell_padding;
18796: $this_method_vars['prevlMargin'] = $prevlMargin;
18797: $this_method_vars['prevrMargin'] = $prevrMargin;
18798: $this_method_vars['curfontname'] = $curfontname;
18799: $this_method_vars['curfontstyle'] = $curfontstyle;
18800: $this_method_vars['curfontsize'] = $curfontsize;
18801: $this_method_vars['curfontascent'] = $curfontascent;
18802: $this_method_vars['curfontdescent'] = $curfontdescent;
18803: $this_method_vars['curfontstretcing'] = $curfontstretcing;
18804: $this_method_vars['curfontkerning'] = $curfontkerning;
18805: $this_method_vars['minstartliney'] = $minstartliney;
18806: $this_method_vars['maxbottomliney'] = $maxbottomliney;
18807: $this_method_vars['yshift'] = $yshift;
18808: $this_method_vars['startlinepage'] = $startlinepage;
18809: $this_method_vars['startlinepos'] = $startlinepos;
18810: $this_method_vars['startlinex'] = $startlinex;
18811: $this_method_vars['startliney'] = $startliney;
18812: $this_method_vars['newline'] = $newline;
18813: $this_method_vars['loop'] = $loop;
18814: $this_method_vars['curpos'] = $curpos;
18815: $this_method_vars['pask'] = $pask;
18816: $this_method_vars['lalign'] = $lalign;
18817: $this_method_vars['plalign'] = $plalign;
18818: $this_method_vars['w'] = $w;
18819: $this_method_vars['prev_cell_height_ratio'] = $prev_cell_height_ratio;
18820: $this_method_vars['prev_listnum'] = $prev_listnum;
18821: $this_method_vars['prev_listordered'] = $prev_listordered;
18822: $this_method_vars['prev_listcount'] = $prev_listcount;
18823: $this_method_vars['prev_lispacer'] = $prev_lispacer;
18824: $this_method_vars['fontaligned'] = $fontaligned;
18825: $this_method_vars['key'] = $key;
18826: $this_method_vars['dom'] = $dom;
18827: }
18828: }
18829:
18830: if (($dom[$key]['value'] == 'tr') AND isset($dom[$key]['thead']) AND $dom[$key]['thead']) {
18831: if (isset($dom[$key]['parent']) AND isset($dom[$dom[$key]['parent']]['thead']) AND !$this->empty_string($dom[$dom[$key]['parent']]['thead'])) {
18832: $this->inthead = true;
18833:
18834: $this->writeHTML($this->thead, false, false, false, false, '');
18835:
18836: if (($this->y < $this->start_transaction_y) OR ($this->checkPageBreak($this->lasth, '', false))) {
18837:
18838:
18839: $this->rollbackTransaction(true);
18840:
18841: foreach ($this_method_vars as $vkey => $vval) {
18842: $$vkey = $vval;
18843: }
18844:
18845: $tmp_thead = $this->thead;
18846: $this->thead = '';
18847:
18848: $pre_y = $this->y;
18849: if ((!$this->checkPageBreak($this->PageBreakTrigger + 1)) AND ($this->y < $pre_y)) {
18850:
18851: $startliney = $this->y;
18852: }
18853: $this->start_transaction_page = $this->page;
18854: $this->start_transaction_y = $this->y;
18855:
18856: $this->thead = $tmp_thead;
18857:
18858: if (isset($dom[$dom[$key]['parent']]['attribute']['cellspacing'])) {
18859: $tmp_cellspacing = $this->getHTMLUnitToUnits($dom[$dom[$key]['parent']]['attribute']['cellspacing'], 1, 'px');
18860: } else {
18861: $tmp_cellspacing = 0;
18862: }
18863: $dom[$dom[$key]['parent']]['borderposition']['page'] = $this->page;
18864: $dom[$dom[$key]['parent']]['borderposition']['column'] = $this->current_column;
18865: $dom[$dom[$key]['parent']]['borderposition']['y'] = $this->y + $tmp_cellspacing;
18866: $xoffset = ($this->x - $dom[$dom[$key]['parent']]['borderposition']['x']);
18867: $dom[$dom[$key]['parent']]['borderposition']['x'] += $xoffset;
18868: $dom[$dom[$key]['parent']]['borderposition']['xmax'] += $xoffset;
18869:
18870: $this->writeHTML($this->thead, false, false, false, false, '');
18871: }
18872: }
18873:
18874: while ( ($key < $maxel) AND (!(
18875: ($dom[$key]['tag'] AND $dom[$key]['opening'] AND ($dom[$key]['value'] == 'tr') AND (!isset($dom[$key]['thead']) OR !$dom[$key]['thead']))
18876: OR ($dom[$key]['tag'] AND (!$dom[$key]['opening']) AND ($dom[$key]['value'] == 'table'))) )) {
18877: ++$key;
18878: }
18879: }
18880: if ($dom[$key]['tag'] OR ($key == 0)) {
18881: if ((($dom[$key]['value'] == 'table') OR ($dom[$key]['value'] == 'tr')) AND (isset($dom[$key]['align']))) {
18882: $dom[$key]['align'] = ($this->rtl) ? 'R' : 'L';
18883: }
18884:
18885: if ((!$this->newline) AND ($dom[$key]['value'] == 'img') AND (isset($dom[$key]['height'])) AND ($dom[$key]['height'] > 0)) {
18886:
18887: $imgh = $this->getHTMLUnitToUnits($dom[$key]['height'], $this->lasth, 'px');
18888:
18889: $autolinebreak = false;
18890: if (isset($dom[$key]['width']) AND ($dom[$key]['width'] > 0)) {
18891: $imgw = $this->getHTMLUnitToUnits($dom[$key]['width'], 1, 'px', false);
18892: if (($this->rtl AND (($this->x - $imgw) < ($this->lMargin + $this->cell_padding['L'])))
18893: OR (!$this->rtl AND (($this->x + $imgw) > ($this->w - $this->rMargin - $this->cell_padding['R'])))) {
18894:
18895: $autolinebreak = true;
18896: $this->Ln('', $cell);
18897:
18898: --$key;
18899: }
18900: }
18901: if (!$autolinebreak) {
18902: if (!$this->InFooter) {
18903: $pre_y = $this->y;
18904:
18905: if ((!$this->checkPageBreak($imgh)) AND ($this->y < $pre_y)) {
18906:
18907: $startliney = $this->y;
18908: }
18909: }
18910: if ($this->page > $startlinepage) {
18911:
18912: if (isset($this->footerlen[$startlinepage])) {
18913: $curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
18914: }
18915:
18916: $pagebuff = $this->getPageBuffer($startlinepage);
18917: $linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos));
18918: $tstart = substr($pagebuff, 0, $startlinepos);
18919: $tend = substr($this->getPageBuffer($startlinepage), $curpos);
18920:
18921: $this->setPageBuffer($startlinepage, $tstart.''.$tend);
18922: $pagebuff = $this->getPageBuffer($this->page);
18923: $tstart = substr($pagebuff, 0, $this->cntmrk[$this->page]);
18924: $tend = substr($pagebuff, $this->cntmrk[$this->page]);
18925:
18926: $yshift = $minstartliney - $this->y;
18927: if ($fontaligned) {
18928: $yshift += ($curfontsize / $this->k);
18929: }
18930: $try = sprintf('1 0 0 1 0 %.3F cm', ($yshift * $this->k));
18931: $this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend);
18932:
18933: if (isset($this->PageAnnots[$this->page])) {
18934: $next_pask = count($this->PageAnnots[$this->page]);
18935: } else {
18936: $next_pask = 0;
18937: }
18938: if (isset($this->PageAnnots[$startlinepage])) {
18939: foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) {
18940: if ($pak >= $pask) {
18941: $this->PageAnnots[$this->page][] = $pac;
18942: unset($this->PageAnnots[$startlinepage][$pak]);
18943: $npak = count($this->PageAnnots[$this->page]) - 1;
18944: $this->PageAnnots[$this->page][$npak]['y'] -= $yshift;
18945: }
18946: }
18947: }
18948: $pask = $next_pask;
18949: $startlinepos = $this->cntmrk[$this->page];
18950: $startlinepage = $this->page;
18951: $startliney = $this->y;
18952: $this->newline = false;
18953: }
18954: $this->y += ((($curfontsize * $this->cell_height_ratio / $this->k) + $curfontascent - $curfontdescent) / 2) - $imgh;
18955: $minstartliney = min($this->y, $minstartliney);
18956: $maxbottomliney = ($startliney + ($this->FontSize * $this->cell_height_ratio));
18957: }
18958: } elseif (isset($dom[$key]['fontname']) OR isset($dom[$key]['fontstyle']) OR isset($dom[$key]['fontsize']) OR isset($dom[$key]['line-height'])) {
18959:
18960: $pfontname = $curfontname;
18961: $pfontstyle = $curfontstyle;
18962: $pfontsize = $curfontsize;
18963: $fontname = isset($dom[$key]['fontname']) ? $dom[$key]['fontname'] : $curfontname;
18964: $fontstyle = isset($dom[$key]['fontstyle']) ? $dom[$key]['fontstyle'] : $curfontstyle;
18965: $fontsize = isset($dom[$key]['fontsize']) ? $dom[$key]['fontsize'] : $curfontsize;
18966: $fontascent = $this->getFontAscent($fontname, $fontstyle, $fontsize);
18967: $fontdescent = $this->getFontDescent($fontname, $fontstyle, $fontsize);
18968: if (($fontname != $curfontname) OR ($fontstyle != $curfontstyle) OR ($fontsize != $curfontsize) OR ($this->cell_height_ratio != $dom[$key]['line-height'])) {
18969: if ((!$this->newline) AND ($key < ($maxel - 1))
18970: AND ((is_numeric($fontsize) AND ($fontsize >= 0) AND is_numeric($curfontsize) AND ($curfontsize >= 0) AND ($fontsize != $curfontsize))
18971: OR ($this->cell_height_ratio != $dom[$key]['line-height']))) {
18972: if ($this->page > $startlinepage) {
18973:
18974: if (isset($this->footerlen[$startlinepage])) {
18975: $curpos = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
18976: }
18977:
18978: $pagebuff = $this->getPageBuffer($startlinepage);
18979: $linebeg = substr($pagebuff, $startlinepos, ($curpos - $startlinepos));
18980: $tstart = substr($pagebuff, 0, $startlinepos);
18981: $tend = substr($this->getPageBuffer($startlinepage), $curpos);
18982:
18983: $this->setPageBuffer($startlinepage, $tstart.''.$tend);
18984: $pagebuff = $this->getPageBuffer($this->page);
18985: $tstart = substr($pagebuff, 0, $this->cntmrk[$this->page]);
18986: $tend = substr($pagebuff, $this->cntmrk[$this->page]);
18987:
18988: $yshift = $minstartliney - $this->y;
18989: $try = sprintf('1 0 0 1 0 %.3F cm', ($yshift * $this->k));
18990: $this->setPageBuffer($this->page, $tstart."\nq\n".$try."\n".$linebeg."\nQ\n".$tend);
18991:
18992: if (isset($this->PageAnnots[$this->page])) {
18993: $next_pask = count($this->PageAnnots[$this->page]);
18994: } else {
18995: $next_pask = 0;
18996: }
18997: if (isset($this->PageAnnots[$startlinepage])) {
18998: foreach ($this->PageAnnots[$startlinepage] as $pak => $pac) {
18999: if ($pak >= $pask) {
19000: $this->PageAnnots[$this->page][] = $pac;
19001: unset($this->PageAnnots[$startlinepage][$pak]);
19002: $npak = count($this->PageAnnots[$this->page]) - 1;
19003: $this->PageAnnots[$this->page][$npak]['y'] -= $yshift;
19004: }
19005: }
19006: }
19007: $pask = $next_pask;
19008: $startlinepos = $this->cntmrk[$this->page];
19009: $startlinepage = $this->page;
19010: $startliney = $this->y;
19011: }
19012: if (!isset($dom[$key]['line-height'])) {
19013: $dom[$key]['line-height'] = $this->cell_height_ratio;
19014: }
19015: if (!$dom[$key]['block']) {
19016: $this->y += (((($curfontsize * $this->cell_height_ratio ) - ($fontsize * $dom[$key]['line-height'])) / $this->k) + $curfontascent - $fontascent - $curfontdescent + $fontdescent) / 2;
19017: if (($dom[$key]['value'] != 'sup') AND ($dom[$key]['value'] != 'sub')) {
19018: $minstartliney = min($this->y, $minstartliney);
19019: $maxbottomliney = max(($this->y + (($fontsize * $this->cell_height_ratio) / $this->k)), $maxbottomliney);
19020: }
19021: }
19022: $this->cell_height_ratio = $dom[$key]['line-height'];
19023: $fontaligned = true;
19024: }
19025: $this->SetFont($fontname, $fontstyle, $fontsize);
19026:
19027: $this->resetLastH();
19028: $curfontname = $fontname;
19029: $curfontstyle = $fontstyle;
19030: $curfontsize = $fontsize;
19031: $curfontascent = $fontascent;
19032: $curfontdescent = $fontdescent;
19033: }
19034: }
19035:
19036: $textstroke = isset($dom[$key]['stroke']) ? $dom[$key]['stroke'] : $this->textstrokewidth;
19037: $textfill = isset($dom[$key]['fill']) ? $dom[$key]['fill'] : (($this->textrendermode % 2) == 0);
19038: $textclip = isset($dom[$key]['clip']) ? $dom[$key]['clip'] : ($this->textrendermode > 3);
19039: $this->setTextRenderingMode($textstroke, $textfill, $textclip);
19040: if (isset($dom[$key]['font-stretch']) AND ($dom[$key]['font-stretch'] !== false)) {
19041: $this->setFontStretching($dom[$key]['font-stretch']);
19042: }
19043: if (isset($dom[$key]['letter-spacing']) AND ($dom[$key]['letter-spacing'] !== false)) {
19044: $this->setFontSpacing($dom[$key]['letter-spacing']);
19045: }
19046: if (($plalign == 'J') AND $dom[$key]['block']) {
19047: $plalign = '';
19048: }
19049:
19050: $curpos = $this->pagelen[$startlinepage];
19051: if (isset($dom[$key]['bgcolor']) AND ($dom[$key]['bgcolor'] !== false)) {
19052: $this->SetFillColorArray($dom[$key]['bgcolor']);
19053: $wfill = true;
19054: } else {
19055: $wfill = $fill | false;
19056: }
19057: if (isset($dom[$key]['fgcolor']) AND ($dom[$key]['fgcolor'] !== false)) {
19058: $this->SetTextColorArray($dom[$key]['fgcolor']);
19059: }
19060: if (isset($dom[$key]['strokecolor']) AND ($dom[$key]['strokecolor'] !== false)) {
19061: $this->SetDrawColorArray($dom[$key]['strokecolor']);
19062: }
19063: if (isset($dom[$key]['align'])) {
19064: $lalign = $dom[$key]['align'];
19065: }
19066: if ($this->empty_string($lalign)) {
19067: $lalign = $align;
19068: }
19069: }
19070:
19071: if ($this->newline AND (strlen($dom[$key]['value']) > 0) AND ($dom[$key]['value'] != 'td') AND ($dom[$key]['value'] != 'th')) {
19072: $newline = true;
19073: $fontaligned = false;
19074:
19075: if (isset($startlinex)) {
19076: $yshift = $minstartliney - $startliney;
19077: if (($yshift > 0) OR ($this->page > $startlinepage)) {
19078: $yshift = 0;
19079: }
19080: $t_x = 0;
19081:
19082: $linew = abs($this->endlinex - $startlinex);
19083: if ($this->inxobj) {
19084:
19085: $pstart = substr($this->xobjects[$this->xobjid]['outdata'], 0, $startlinepos);
19086: if (isset($opentagpos)) {
19087: $midpos = $opentagpos;
19088: } else {
19089: $midpos = 0;
19090: }
19091: if ($midpos > 0) {
19092: $pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos, ($midpos - $startlinepos));
19093: $pend = substr($this->xobjects[$this->xobjid]['outdata'], $midpos);
19094: } else {
19095: $pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos);
19096: $pend = '';
19097: }
19098: } else {
19099: $pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos);
19100: if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
19101: $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
19102: $midpos = min($opentagpos, $this->footerpos[$startlinepage]);
19103: } elseif (isset($opentagpos)) {
19104: $midpos = $opentagpos;
19105: } elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
19106: $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
19107: $midpos = $this->footerpos[$startlinepage];
19108: } else {
19109: $midpos = 0;
19110: }
19111: if ($midpos > 0) {
19112: $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos));
19113: $pend = substr($this->getPageBuffer($startlinepage), $midpos);
19114: } else {
19115: $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos);
19116: $pend = '';
19117: }
19118: }
19119: if ((isset($plalign) AND ((($plalign == 'C') OR ($plalign == 'J') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl)))))) {
19120:
19121: $tw = $w;
19122: if (($plalign == 'J') AND $this->isRTLTextDir() AND ($this->num_columns > 1)) {
19123: $tw += $this->cell_padding['R'];
19124: }
19125: if ($this->lMargin != $prevlMargin) {
19126: $tw += ($prevlMargin - $this->lMargin);
19127: }
19128: if ($this->rMargin != $prevrMargin) {
19129: $tw += ($prevrMargin - $this->rMargin);
19130: }
19131: $one_space_width = $this->GetStringWidth(chr(32));
19132: $no = 0;
19133: if ($this->isRTLTextDir()) {
19134:
19135: $pos1 = $this->revstrpos($pmid, '[(');
19136: if ($pos1 > 0) {
19137: $pos1 = intval($pos1);
19138: if ($this->isUnicodeFont()) {
19139: $pos2 = intval($this->revstrpos($pmid, '[('.chr(0).chr(32)));
19140: $spacelen = 2;
19141: } else {
19142: $pos2 = intval($this->revstrpos($pmid, '[('.chr(32)));
19143: $spacelen = 1;
19144: }
19145: if ($pos1 == $pos2) {
19146: $pmid = substr($pmid, 0, ($pos1 + 2)).substr($pmid, ($pos1 + 2 + $spacelen));
19147: if (substr($pmid, $pos1, 4) == '[()]') {
19148: $linew -= $one_space_width;
19149: } elseif ($pos1 == strpos($pmid, '[(')) {
19150: $no = 1;
19151: }
19152: }
19153: }
19154: } else {
19155:
19156: $pos1 = $this->revstrpos($pmid, ')]');
19157: if ($pos1 > 0) {
19158: $pos1 = intval($pos1);
19159: if ($this->isUnicodeFont()) {
19160: $pos2 = intval($this->revstrpos($pmid, chr(0).chr(32).')]')) + 2;
19161: $spacelen = 2;
19162: } else {
19163: $pos2 = intval($this->revstrpos($pmid, chr(32).')]')) + 1;
19164: $spacelen = 1;
19165: }
19166: if ($pos1 == $pos2) {
19167: $pmid = substr($pmid, 0, ($pos1 - $spacelen)).substr($pmid, $pos1);
19168: $linew -= $one_space_width;
19169: }
19170: }
19171: }
19172: $mdiff = ($tw - $linew);
19173: if ($plalign == 'C') {
19174: if ($this->rtl) {
19175: $t_x = -($mdiff / 2);
19176: } else {
19177: $t_x = ($mdiff / 2);
19178: }
19179: } elseif ($plalign == 'R') {
19180:
19181: $t_x = $mdiff;
19182: } elseif ($plalign == 'L') {
19183:
19184: $t_x = -$mdiff;
19185: } elseif (($plalign == 'J') AND ($plalign == $lalign)) {
19186:
19187: if ($this->isRTLTextDir()) {
19188:
19189: $t_x = -$mdiff;
19190: }
19191: $ns = 0;
19192: $pmidtemp = $pmid;
19193:
19194: $pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp);
19195: $pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp);
19196:
19197: if (preg_match_all('/\[\(([^\)]*)\)\]/x', $pmidtemp, $lnstring, PREG_PATTERN_ORDER)) {
19198: $spacestr = $this->getSpaceString();
19199: $maxkk = count($lnstring[1]) - 1;
19200: for ($kk=0; $kk <= $maxkk; ++$kk) {
19201:
19202: $lnstring[1][$kk] = str_replace('#!#OP#!#', '(', $lnstring[1][$kk]);
19203: $lnstring[1][$kk] = str_replace('#!#CP#!#', ')', $lnstring[1][$kk]);
19204:
19205: $lnstring[2][$kk] = substr_count($lnstring[1][$kk], $spacestr);
19206:
19207: $ns += $lnstring[2][$kk];
19208: $lnstring[3][$kk] = $ns;
19209: }
19210: if ($ns == 0) {
19211: $ns = 1;
19212: }
19213:
19214: $spacewidth = ($mdiff / ($ns - $no)) * $this->k;
19215: $spacewidthu = -1000 * ($mdiff + (($ns + $no) * $one_space_width)) / $ns / $this->FontSize;
19216: if ($this->font_spacing != 0) {
19217:
19218: $osw = -1000 * $this->font_spacing / $this->FontSize;
19219: $spacewidthu += $osw;
19220: }
19221: $nsmax = $ns;
19222: $ns = 0;
19223: reset($lnstring);
19224: $offset = 0;
19225: $strcount = 0;
19226: $prev_epsposbeg = 0;
19227: $textpos = 0;
19228: if ($this->isRTLTextDir()) {
19229: $textpos = $this->wPt;
19230: }
19231: global $spacew;
19232: while (preg_match('/([0-9\.\+\-]*)[\s](Td|cm|m|l|c|re)[\s]/x', $pmid, $strpiece, PREG_OFFSET_CAPTURE, $offset) == 1) {
19233:
19234: $stroffset = strpos($pmid, '[(', $offset);
19235: if (($stroffset !== false) AND ($stroffset <= $strpiece[2][1])) {
19236:
19237: $offset = strpos($pmid, ')]', $stroffset);
19238: while (($offset !== false) AND ($pmid{($offset - 1)} == '\\')) {
19239: $offset = strpos($pmid, ')]', ($offset + 1));
19240: }
19241: if ($offset === false) {
19242: $this->Error('HTML Justification: malformed PDF code.');
19243: }
19244: continue;
19245: }
19246: if ($this->isRTLTextDir()) {
19247: $spacew = ($spacewidth * ($nsmax - $ns));
19248: } else {
19249: $spacew = ($spacewidth * $ns);
19250: }
19251: $offset = $strpiece[2][1] + strlen($strpiece[2][0]);
19252: $epsposbeg = strpos($pmid, 'q'.$this->epsmarker, $offset);
19253: $epsposend = strpos($pmid, $this->epsmarker.'Q', $offset) + strlen($this->epsmarker.'Q');
19254: if ((($epsposbeg > 0) AND ($epsposend > 0) AND ($offset > $epsposbeg) AND ($offset < $epsposend))
19255: OR (($epsposbeg === false) AND ($epsposend > 0) AND ($offset < $epsposend))) {
19256:
19257: $trx = sprintf('1 0 0 1 %.3F 0 cm', $spacew);
19258: $epsposbeg = strpos($pmid, 'q'.$this->epsmarker, ($prev_epsposbeg - 6));
19259: $pmid_b = substr($pmid, 0, $epsposbeg);
19260: $pmid_m = substr($pmid, $epsposbeg, ($epsposend - $epsposbeg));
19261: $pmid_e = substr($pmid, $epsposend);
19262: $pmid = $pmid_b."\nq\n".$trx."\n".$pmid_m."\nQ\n".$pmid_e;
19263: $offset = $epsposend;
19264: continue;
19265:
19266: }
19267: $prev_epsposbeg = $epsposbeg;
19268: $currentxpos = 0;
19269:
19270: switch ($strpiece[2][0]) {
19271: case 'Td':
19272: case 'cm':
19273: case 'm':
19274: case 'l': {
19275:
19276: preg_match('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x', $pmid, $xmatches);
19277: $currentxpos = $xmatches[1];
19278: $textpos = $currentxpos;
19279: if (($strcount <= $maxkk) AND ($strpiece[2][0] == 'Td')) {
19280: $ns = $lnstring[3][$strcount];
19281: if ($this->isRTLTextDir()) {
19282: $spacew = ($spacewidth * ($nsmax - $ns));
19283: }
19284: ++$strcount;
19285: }
19286:
19287: $pmid = preg_replace_callback('/([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s]('.$strpiece[2][0].')([\s]*)/x',
19288: create_function('$matches', 'global $spacew;
19289: $newx = sprintf("%.2F",(floatval($matches[1]) + $spacew));
19290: return "".$newx." ".$matches[2]." x*#!#*x".$matches[3].$matches[4];'), $pmid, 1);
19291: break;
19292: }
19293: case 're': {
19294:
19295: if (!$this->empty_string($this->lispacer)) {
19296: $this->lispacer = '';
19297: continue;
19298: }
19299: preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s](re)([\s]*)/x', $pmid, $xmatches);
19300: $currentxpos = $xmatches[1];
19301: global $x_diff, $w_diff;
19302: $x_diff = 0;
19303: $w_diff = 0;
19304: if ($this->isRTLTextDir()) {
19305: if ($currentxpos < $textpos) {
19306: $x_diff = ($spacewidth * ($nsmax - $lnstring[3][$strcount]));
19307: $w_diff = ($spacewidth * $lnstring[2][$strcount]);
19308: } else {
19309: if ($strcount > 0) {
19310: $x_diff = ($spacewidth * ($nsmax - $lnstring[3][($strcount - 1)]));
19311: $w_diff = ($spacewidth * $lnstring[2][($strcount - 1)]);
19312: }
19313: }
19314: } else {
19315: if ($currentxpos > $textpos) {
19316: if ($strcount > 0) {
19317: $x_diff = ($spacewidth * $lnstring[3][($strcount - 1)]);
19318: }
19319: $w_diff = ($spacewidth * $lnstring[2][$strcount]);
19320: } else {
19321: if ($strcount > 1) {
19322: $x_diff = ($spacewidth * $lnstring[3][($strcount - 2)]);
19323: }
19324: if ($strcount > 0) {
19325: $w_diff = ($spacewidth * $lnstring[2][($strcount - 1)]);
19326: }
19327: }
19328: }
19329: $pmid = preg_replace_callback('/('.$xmatches[1].')[\s]('.$xmatches[2].')[\s]('.$xmatches[3].')[\s]('.$strpiece[1][0].')[\s](re)([\s]*)/x',
19330: create_function('$matches', 'global $x_diff, $w_diff;
19331: $newx = sprintf("%.2F",(floatval($matches[1]) + $x_diff));
19332: $neww = sprintf("%.2F",(floatval($matches[3]) + $w_diff));
19333: return "".$newx." ".$matches[2]." ".$neww." ".$matches[4]." x*#!#*x".$matches[5].$matches[6];'), $pmid, 1);
19334: break;
19335: }
19336: case 'c': {
19337:
19338: preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s](c)([\s]*)/x', $pmid, $xmatches);
19339: $currentxpos = $xmatches[1];
19340:
19341: $pmid = preg_replace_callback('/('.$xmatches[1].')[\s]('.$xmatches[2].')[\s]('.$xmatches[3].')[\s]('.$xmatches[4].')[\s]('.$xmatches[5].')[\s]('.$strpiece[1][0].')[\s](c)([\s]*)/x',
19342: create_function('$matches', 'global $spacew;
19343: $newx1 = sprintf("%.3F",(floatval($matches[1]) + $spacew));
19344: $newx2 = sprintf("%.3F",(floatval($matches[3]) + $spacew));
19345: $newx3 = sprintf("%.3F",(floatval($matches[5]) + $spacew));
19346: return "".$newx1." ".$matches[2]." ".$newx2." ".$matches[4]." ".$newx3." ".$matches[6]." x*#!#*x".$matches[7].$matches[8];'), $pmid, 1);
19347: break;
19348: }
19349: }
19350:
19351: $cxpos = ($currentxpos / $this->k);
19352: $lmpos = ($this->lMargin + $this->cell_padding['L'] + $this->feps);
19353: if ($this->inxobj) {
19354:
19355: foreach ($this->xobjects[$this->xobjid]['annotations'] as $pak => $pac) {
19356: if (($pac['y'] >= $minstartliney) AND (($pac['x'] * $this->k) >= ($currentxpos - $this->feps)) AND (($pac['x'] * $this->k) <= ($currentxpos + $this->feps))) {
19357: if ($cxpos > $lmpos) {
19358: $this->xobjects[$this->xobjid]['annotations'][$pak]['x'] += ($spacew / $this->k);
19359: $this->xobjects[$this->xobjid]['annotations'][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k);
19360: } else {
19361: $this->xobjects[$this->xobjid]['annotations'][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k);
19362: }
19363: break;
19364: }
19365: }
19366: } elseif (isset($this->PageAnnots[$this->page])) {
19367: foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
19368: if (($pac['y'] >= $minstartliney) AND (($pac['x'] * $this->k) >= ($currentxpos - $this->feps)) AND (($pac['x'] * $this->k) <= ($currentxpos + $this->feps))) {
19369: if ($cxpos > $lmpos) {
19370: $this->PageAnnots[$this->page][$pak]['x'] += ($spacew / $this->k);
19371: $this->PageAnnots[$this->page][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k);
19372: } else {
19373: $this->PageAnnots[$this->page][$pak]['w'] += (($spacewidth * $pac['numspaces']) / $this->k);
19374: }
19375: break;
19376: }
19377: }
19378: }
19379: }
19380:
19381: $pmid = str_replace('x*#!#*x', '', $pmid);
19382: if ($this->isUnicodeFont()) {
19383:
19384: $spacew = $spacewidthu;
19385: if ($this->font_stretching != 100) {
19386:
19387: $spacew /= ($this->font_stretching / 100);
19388: }
19389: $pmidtemp = $pmid;
19390:
19391: $pmidtemp = preg_replace('/[\\\][\(]/x', '\\#!#OP#!#', $pmidtemp);
19392: $pmidtemp = preg_replace('/[\\\][\)]/x', '\\#!#CP#!#', $pmidtemp);
19393: $pmid = preg_replace_callback("/\[\(([^\)]*)\)\]/x",
19394: create_function('$matches', 'global $spacew;
19395: $matches[1] = str_replace("#!#OP#!#", "(", $matches[1]);
19396: $matches[1] = str_replace("#!#CP#!#", ")", $matches[1]);
19397: return "[(".str_replace(chr(0).chr(32), ") ".sprintf("%.3F", $spacew)." (", $matches[1]).")]";'), $pmidtemp);
19398: if ($this->inxobj) {
19399:
19400: $this->xobjects[$this->xobjid]['outdata'] = $pstart."\n".$pmid."\n".$pend;
19401: } else {
19402: $this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\n".$pend);
19403: }
19404: $endlinepos = strlen($pstart."\n".$pmid."\n");
19405: } else {
19406:
19407: if ($this->font_stretching != 100) {
19408:
19409: $spacewidth /= ($this->font_stretching / 100);
19410: }
19411: $rs = sprintf('%.3F Tw', $spacewidth);
19412: $pmid = preg_replace("/\[\(/x", $rs.' [(', $pmid);
19413: if ($this->inxobj) {
19414:
19415: $this->xobjects[$this->xobjid]['outdata'] = $pstart."\n".$pmid."\nBT 0 Tw ET\n".$pend;
19416: } else {
19417: $this->setPageBuffer($startlinepage, $pstart."\n".$pmid."\nBT 0 Tw ET\n".$pend);
19418: }
19419: $endlinepos = strlen($pstart."\n".$pmid."\nBT 0 Tw ET\n");
19420: }
19421: }
19422: }
19423: }
19424: if (($t_x != 0) OR ($yshift < 0)) {
19425:
19426: $trx = sprintf('1 0 0 1 %.3F %.3F cm', ($t_x * $this->k), ($yshift * $this->k));
19427: $pstart .= "\nq\n".$trx."\n".$pmid."\nQ\n";
19428: $endlinepos = strlen($pstart);
19429: if ($this->inxobj) {
19430:
19431: $this->xobjects[$this->xobjid]['outdata'] = $pstart.$pend;
19432: foreach ($this->xobjects[$this->xobjid]['annotations'] as $pak => $pac) {
19433: if ($pak >= $pask) {
19434: $this->xobjects[$this->xobjid]['annotations'][$pak]['x'] += $t_x;
19435: $this->xobjects[$this->xobjid]['annotations'][$pak]['y'] -= $yshift;
19436: }
19437: }
19438: } else {
19439: $this->setPageBuffer($startlinepage, $pstart.$pend);
19440:
19441: if (isset($this->PageAnnots[$this->page])) {
19442: foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
19443: if ($pak >= $pask) {
19444: $this->PageAnnots[$this->page][$pak]['x'] += $t_x;
19445: $this->PageAnnots[$this->page][$pak]['y'] -= $yshift;
19446: }
19447: }
19448: }
19449: }
19450: $this->y -= $yshift;
19451: }
19452: }
19453: $pbrk = $this->checkPageBreak($this->lasth);
19454: $this->newline = false;
19455: $startlinex = $this->x;
19456: $startliney = $this->y;
19457: if ($dom[$dom[$key]['parent']]['value'] == 'sup') {
19458: $startliney -= ((0.3 * $this->FontSizePt) / $this->k);
19459: } elseif ($dom[$dom[$key]['parent']]['value'] == 'sub') {
19460: $startliney -= (($this->FontSizePt / 0.7) / $this->k);
19461: } else {
19462: $minstartliney = $startliney;
19463: $maxbottomliney = ($this->y + (($fontsize * $this->cell_height_ratio) / $this->k));
19464: }
19465: $startlinepage = $this->page;
19466: if (isset($endlinepos) AND (!$pbrk)) {
19467: $startlinepos = $endlinepos;
19468: } else {
19469: if ($this->inxobj) {
19470:
19471: $startlinepos = strlen($this->xobjects[$this->xobjid]['outdata']);
19472: } elseif (!$this->InFooter) {
19473: if (isset($this->footerlen[$this->page])) {
19474: $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
19475: } else {
19476: $this->footerpos[$this->page] = $this->pagelen[$this->page];
19477: }
19478: $startlinepos = $this->footerpos[$this->page];
19479: } else {
19480: $startlinepos = $this->pagelen[$this->page];
19481: }
19482: }
19483: unset($endlinepos);
19484: $plalign = $lalign;
19485: if (isset($this->PageAnnots[$this->page])) {
19486: $pask = count($this->PageAnnots[$this->page]);
19487: } else {
19488: $pask = 0;
19489: }
19490: if (!($dom[$key]['tag'] AND !$dom[$key]['opening'] AND ($dom[$key]['value'] == 'table') AND ($this->emptypagemrk[$this->page] == $this->pagelen[$this->page]))) {
19491: $this->SetFont($fontname, $fontstyle, $fontsize);
19492: if ($wfill) {
19493: $this->SetFillColorArray($this->bgcolor);
19494: }
19495: }
19496: }
19497: if (isset($opentagpos)) {
19498: unset($opentagpos);
19499: }
19500: if ($dom[$key]['tag']) {
19501: if ($dom[$key]['opening']) {
19502:
19503: if (isset($dom[$key]['text-indent']) AND $dom[$key]['block']) {
19504: $this->textindent = $dom[$key]['text-indent'];
19505: $this->newline = true;
19506: }
19507:
19508: if ($dom[$key]['value'] == 'table') {
19509:
19510: if ($this->rtl) {
19511: $wtmp = $this->x - $this->lMargin;
19512: } else {
19513: $wtmp = $this->w - $this->rMargin - $this->x;
19514: }
19515: if (isset($dom[$key]['attribute']['cellspacing'])) {
19516: $cellspacing = $this->getHTMLUnitToUnits($dom[$key]['attribute']['cellspacing'], 1, 'px');
19517: } else {
19518: $cellspacing = 0;
19519: }
19520:
19521: if (isset($dom[$key]['width'])) {
19522: $table_width = $this->getHTMLUnitToUnits($dom[$key]['width'], $wtmp, 'px');
19523: } else {
19524: $table_width = $wtmp;
19525: }
19526: $table_width -= (2 * $cellspacing);
19527: if (!$this->inthead) {
19528: $this->y += $cellspacing;
19529: }
19530: if ($this->rtl) {
19531: $cellspacingx = -$cellspacing;
19532: } else {
19533: $cellspacingx = $cellspacing;
19534: }
19535:
19536: $table_columns_width = ($table_width - ($cellspacing * ($dom[$key]['cols'] - 1)));
19537:
19538: $table_min_column_width = ($table_columns_width / $dom[$key]['cols']);
19539:
19540: $table_colwidths = array_fill(0, $dom[$key]['cols'], $table_min_column_width);
19541: }
19542:
19543: if ($dom[$key]['value'] == 'tr') {
19544:
19545: $colid = 0;
19546: }
19547:
19548: if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) {
19549: $trid = $dom[$key]['parent'];
19550: $table_el = $dom[$trid]['parent'];
19551: if (!isset($dom[$table_el]['cols'])) {
19552: $dom[$table_el]['cols'] = $dom[$trid]['cols'];
19553: }
19554:
19555: $tdborder = 0;
19556: if (isset($dom[$key]['border']) AND !empty($dom[$key]['border'])) {
19557: $tdborder = $dom[$key]['border'];
19558: }
19559: $colspan = $dom[$key]['attribute']['colspan'];
19560: $old_cell_padding = $this->cell_padding;
19561: if (isset($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'])) {
19562: $current_cell_padding = $this->getHTMLUnitToUnits($dom[($dom[$trid]['parent'])]['attribute']['cellpadding'], 1, 'px');
19563: } else {
19564: $current_cell_padding = 0;
19565: }
19566: $this->SetCellPadding($current_cell_padding);
19567: if (isset($dom[$key]['height'])) {
19568:
19569: $cellh = $this->getHTMLUnitToUnits($dom[$key]['height'], 0, 'px');
19570: } else {
19571: $cellh = 0;
19572: }
19573: if (isset($dom[$key]['content'])) {
19574: $cell_content = $dom[$key]['content'];
19575: } else {
19576: $cell_content = ' ';
19577: }
19578: $tagtype = $dom[$key]['value'];
19579: $parentid = $key;
19580: while (($key < $maxel) AND (!(($dom[$key]['tag']) AND (!$dom[$key]['opening']) AND ($dom[$key]['value'] == $tagtype) AND ($dom[$key]['parent'] == $parentid)))) {
19581:
19582: ++$key;
19583: }
19584: if (!isset($dom[$trid]['startpage'])) {
19585: $dom[$trid]['startpage'] = $this->page;
19586: } else {
19587: $this->setPage($dom[$trid]['startpage']);
19588: }
19589: if (!isset($dom[$trid]['startcolumn'])) {
19590: $dom[$trid]['startcolumn'] = $this->current_column;
19591: } elseif ($this->current_column != $dom[$trid]['startcolumn']) {
19592: $tmpx = $this->x;
19593: $this->selectColumn($dom[$trid]['startcolumn']);
19594: $this->x = $tmpx;
19595: }
19596: if (!isset($dom[$trid]['starty'])) {
19597: $dom[$trid]['starty'] = $this->y;
19598: } else {
19599: $this->y = $dom[$trid]['starty'];
19600: }
19601: if (!isset($dom[$trid]['startx'])) {
19602: $dom[$trid]['startx'] = $this->x;
19603: $this->x += $cellspacingx;
19604: } else {
19605: $this->x += ($cellspacingx / 2);
19606: }
19607: if (isset($dom[$parentid]['attribute']['rowspan'])) {
19608: $rowspan = intval($dom[$parentid]['attribute']['rowspan']);
19609: } else {
19610: $rowspan = 1;
19611: }
19612:
19613: if (isset($dom[$table_el]['rowspans'])) {
19614: $rsk = 0;
19615: $rskmax = count($dom[$table_el]['rowspans']);
19616: while ($rsk < $rskmax) {
19617: $trwsp = $dom[$table_el]['rowspans'][$rsk];
19618: $rsstartx = $trwsp['startx'];
19619: $rsendx = $trwsp['endx'];
19620:
19621: if ($trwsp['startpage'] < $this->page) {
19622: if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$trwsp['startpage']]['orm'])) {
19623: $dl = ($this->pagedim[$this->page]['orm'] - $this->pagedim[$trwsp['startpage']]['orm']);
19624: $rsstartx -= $dl;
19625: $rsendx -= $dl;
19626: } elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$trwsp['startpage']]['olm'])) {
19627: $dl = ($this->pagedim[$this->page]['olm'] - $this->pagedim[$trwsp['startpage']]['olm']);
19628: $rsstartx += $dl;
19629: $rsendx += $dl;
19630: }
19631: }
19632: if (($trwsp['rowspan'] > 0)
19633: AND ($rsstartx > ($this->x - $cellspacing - $current_cell_padding - $this->feps))
19634: AND ($rsstartx < ($this->x + $cellspacing + $current_cell_padding + $this->feps))
19635: AND (($trwsp['starty'] < ($this->y - $this->feps)) OR ($trwsp['startpage'] < $this->page) OR ($trwsp['startcolumn'] < $this->current_column))) {
19636:
19637: $this->x = $rsendx + $cellspacingx;
19638:
19639: $colid += $trwsp['colspan'];
19640: if (($trwsp['rowspan'] == 1)
19641: AND (isset($dom[$trid]['endy']))
19642: AND (isset($dom[$trid]['endpage']))
19643: AND (isset($dom[$trid]['endcolumn']))
19644: AND ($trwsp['endpage'] == $dom[$trid]['endpage'])
19645: AND ($trwsp['endcolumn'] == $dom[$trid]['endcolumn'])) {
19646:
19647: $dom[$table_el]['rowspans'][$rsk]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']);
19648: $dom[$trid]['endy'] = $dom[$table_el]['rowspans'][$rsk]['endy'];
19649: }
19650: $rsk = 0;
19651: } else {
19652: ++$rsk;
19653: }
19654: }
19655: }
19656: if (isset($dom[$parentid]['width'])) {
19657:
19658: $cellw = $this->getHTMLUnitToUnits($dom[$parentid]['width'], $table_columns_width, 'px');
19659: $tmpcw = ($cellw / $colspan);
19660: for ($i = 0; $i < $colspan; ++$i) {
19661: $table_colwidths[($colid + $i)] = $tmpcw;
19662: }
19663: } else {
19664:
19665: $cellw = 0;
19666: for ($i = 0; $i < $colspan; ++$i) {
19667: $cellw += $table_colwidths[($colid + $i)];
19668: }
19669: }
19670: $cellw += (($colspan - 1) * $cellspacing);
19671:
19672: $colid += $colspan;
19673:
19674: if ($rowspan > 1) {
19675: $trsid = array_push($dom[$table_el]['rowspans'], array('trid' => $trid, 'rowspan' => $rowspan, 'mrowspan' => $rowspan, 'colspan' => $colspan, 'startpage' => $this->page, 'startcolumn' => $this->current_column, 'startx' => $this->x, 'starty' => $this->y));
19676: }
19677: $cellid = array_push($dom[$trid]['cellpos'], array('startx' => $this->x));
19678: if ($rowspan > 1) {
19679: $dom[$trid]['cellpos'][($cellid - 1)]['rowspanid'] = ($trsid - 1);
19680: }
19681:
19682: if (isset($dom[$parentid]['bgcolor']) AND ($dom[$parentid]['bgcolor'] !== false)) {
19683: $dom[$trid]['cellpos'][($cellid - 1)]['bgcolor'] = $dom[$parentid]['bgcolor'];
19684: }
19685:
19686: if (isset($tdborder) AND !empty($tdborder)) {
19687: $dom[$trid]['cellpos'][($cellid - 1)]['border'] = $tdborder;
19688: }
19689: $prevLastH = $this->lasth;
19690:
19691: if ($this->rtl) {
19692: $this->colxshift['x'] = $this->w - $this->x - $this->rMargin;
19693: } else {
19694: $this->colxshift['x'] = $this->x - $this->lMargin;
19695: }
19696: $this->colxshift['s'] = $cellspacing;
19697: $this->colxshift['p'] = $current_cell_padding;
19698:
19699: $this->MultiCell($cellw, $cellh, $cell_content, false, $lalign, false, 2, '', '', true, 0, true);
19700:
19701: $this->colxshift = array('x' => 0, 's' => 0, 'p' => 0);
19702: $this->lasth = $prevLastH;
19703: $this->cell_padding = $old_cell_padding;
19704: $dom[$trid]['cellpos'][($cellid - 1)]['endx'] = $this->x;
19705:
19706: if ($rowspan <= 1) {
19707: if (isset($dom[$trid]['endy'])) {
19708: if (($this->page == $dom[$trid]['endpage']) AND ($this->current_column == $dom[$trid]['endcolumn'])) {
19709: $dom[$trid]['endy'] = max($this->y, $dom[$trid]['endy']);
19710: } elseif (($this->page > $dom[$trid]['endpage']) OR ($this->current_column > $dom[$trid]['endcolumn'])) {
19711: $dom[$trid]['endy'] = $this->y;
19712: }
19713: } else {
19714: $dom[$trid]['endy'] = $this->y;
19715: }
19716: if (isset($dom[$trid]['endpage'])) {
19717: $dom[$trid]['endpage'] = max($this->page, $dom[$trid]['endpage']);
19718: } else {
19719: $dom[$trid]['endpage'] = $this->page;
19720: }
19721: if (isset($dom[$trid]['endcolumn'])) {
19722: $dom[$trid]['endcolumn'] = max($this->current_column, $dom[$trid]['endcolumn']);
19723: } else {
19724: $dom[$trid]['endcolumn'] = $this->current_column;
19725: }
19726: } else {
19727:
19728: $dom[$table_el]['rowspans'][($trsid - 1)]['endx'] = $this->x;
19729: $dom[$table_el]['rowspans'][($trsid - 1)]['endy'] = $this->y;
19730: $dom[$table_el]['rowspans'][($trsid - 1)]['endpage'] = $this->page;
19731: $dom[$table_el]['rowspans'][($trsid - 1)]['endcolumn'] = $this->current_column;
19732: }
19733: if (isset($dom[$table_el]['rowspans'])) {
19734:
19735: foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
19736: if ($trwsp['rowspan'] > 0) {
19737: if (isset($dom[$trid]['endpage'])) {
19738: if (($trwsp['endpage'] == $dom[$trid]['endpage']) AND ($trwsp['endcolumn'] == $dom[$trid]['endcolumn'])) {
19739: $dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$trid]['endy'], $trwsp['endy']);
19740: } elseif (($trwsp['endpage'] < $dom[$trid]['endpage']) OR ($trwsp['endcolumn'] < $dom[$trid]['endcolumn'])) {
19741: $dom[$table_el]['rowspans'][$k]['endy'] = $dom[$trid]['endy'];
19742: $dom[$table_el]['rowspans'][$k]['endpage'] = $dom[$trid]['endpage'];
19743: $dom[$table_el]['rowspans'][$k]['endcolumn'] = $dom[$trid]['endcolumn'];
19744: } else {
19745: $dom[$trid]['endy'] = $this->pagedim[$dom[$trid]['endpage']]['hk'] - $this->pagedim[$dom[$trid]['endpage']]['bm'];
19746: }
19747: }
19748: }
19749: }
19750: }
19751: $this->x += ($cellspacingx / 2);
19752: } else {
19753:
19754: if (!isset($opentagpos)) {
19755: if ($this->inxobj) {
19756:
19757: $opentagpos = strlen($this->xobjects[$this->xobjid]['outdata']);
19758: } elseif (!$this->InFooter) {
19759: if (isset($this->footerlen[$this->page])) {
19760: $this->footerpos[$this->page] = $this->pagelen[$this->page] - $this->footerlen[$this->page];
19761: } else {
19762: $this->footerpos[$this->page] = $this->pagelen[$this->page];
19763: }
19764: $opentagpos = $this->footerpos[$this->page];
19765: }
19766: }
19767: $this->openHTMLTagHandler($dom, $key, $cell);
19768: }
19769: } else {
19770: $prev_numpages = $this->numpages;
19771: $old_bordermrk = $this->bordermrk[$this->page];
19772: $this->closeHTMLTagHandler($dom, $key, $cell, $maxbottomliney);
19773: if ($this->bordermrk[$this->page] > $old_bordermrk) {
19774: $startlinepos += ($this->bordermrk[$this->page] - $old_bordermrk);
19775: }
19776: if ($prev_numpages > $this->numpages) {
19777: $startlinepage = $this->page;
19778: }
19779: }
19780: } elseif (strlen($dom[$key]['value']) > 0) {
19781:
19782: if (!$this->empty_string($this->lispacer) AND ($this->lispacer != '^')) {
19783: $this->SetFont($pfontname, $pfontstyle, $pfontsize);
19784: $this->resetLastH();
19785: $minstartliney = $this->y;
19786: $maxbottomliney = ($startliney + ($this->FontSize * $this->cell_height_ratio));
19787: $this->putHtmlListBullet($this->listnum, $this->lispacer, $pfontsize);
19788: $this->SetFont($curfontname, $curfontstyle, $curfontsize);
19789: $this->resetLastH();
19790: if (is_numeric($pfontsize) AND ($pfontsize > 0) AND is_numeric($curfontsize) AND ($curfontsize > 0) AND ($pfontsize != $curfontsize)) {
19791: $pfontascent = $this->getFontAscent($pfontname, $pfontstyle, $pfontsize);
19792: $pfontdescent = $this->getFontDescent($pfontname, $pfontstyle, $pfontsize);
19793: $this->y += ((($pfontsize - $curfontsize) * $this->cell_height_ratio / $this->k) + $pfontascent - $curfontascent - $pfontdescent + $curfontdescent) / 2;
19794: $minstartliney = min($this->y, $minstartliney);
19795: $maxbottomliney = max(($this->y + (($pfontsize * $this->cell_height_ratio) / $this->k)), $maxbottomliney);
19796: }
19797: }
19798:
19799: $this->htmlvspace = 0;
19800: if ((!$this->premode) AND $this->isRTLTextDir()) {
19801:
19802: $lsp = '';
19803: $rsp = '';
19804: if (preg_match('/^('.$this->re_space['p'].'+)/'.$this->re_space['m'], $dom[$key]['value'], $matches)) {
19805: $lsp = $matches[1];
19806: }
19807: if (preg_match('/('.$this->re_space['p'].'+)$/'.$this->re_space['m'], $dom[$key]['value'], $matches)) {
19808: $rsp = $matches[1];
19809: }
19810: $dom[$key]['value'] = $rsp.$this->stringTrim($dom[$key]['value']).$lsp;
19811: }
19812: if ($newline) {
19813: if (!$this->premode) {
19814: $prelen = strlen($dom[$key]['value']);
19815: if ($this->isRTLTextDir()) {
19816:
19817: $dom[$key]['value'] = $this->stringRightTrim($dom[$key]['value']);
19818: } else {
19819:
19820: $dom[$key]['value'] = $this->stringLeftTrim($dom[$key]['value']);
19821: }
19822: $postlen = strlen($dom[$key]['value']);
19823: if (($postlen == 0) AND ($prelen > 0)) {
19824: $dom[$key]['trimmed_space'] = true;
19825: }
19826: }
19827: $newline = false;
19828: $firstblock = true;
19829: } else {
19830: $firstblock = false;
19831:
19832: $dom[$key]['value'] = preg_replace('/^'.$this->re_space['p'].'+$/'.$this->re_space['m'], chr(32), $dom[$key]['value']);
19833: }
19834: $strrest = '';
19835: if ($this->rtl) {
19836: $this->x -= $this->textindent;
19837: } else {
19838: $this->x += $this->textindent;
19839: }
19840: if (!isset($dom[$key]['trimmed_space']) OR !$dom[$key]['trimmed_space']) {
19841: if (!empty($this->HREF) AND (isset($this->HREF['url']))) {
19842:
19843: $hrefcolor = '';
19844: if (isset($dom[($dom[$key]['parent'])]['fgcolor']) AND ($dom[($dom[$key]['parent'])]['fgcolor'] !== false)) {
19845: $hrefcolor = $dom[($dom[$key]['parent'])]['fgcolor'];
19846: }
19847: $hrefstyle = -1;
19848: if (isset($dom[($dom[$key]['parent'])]['fontstyle']) AND ($dom[($dom[$key]['parent'])]['fontstyle'] !== false)) {
19849: $hrefstyle = $dom[($dom[$key]['parent'])]['fontstyle'];
19850: }
19851: $strrest = $this->addHtmlLink($this->HREF['url'], $dom[$key]['value'], $wfill, true, $hrefcolor, $hrefstyle, true);
19852: } else {
19853: $wadj = 0;
19854: $adjblks = 0;
19855:
19856: $nkey = ($key + 1);
19857: $write_block = true;
19858: $tmp_fontname = $this->FontFamily;
19859: $tmp_fontstyle = $this->FontStyle;
19860: $tmp_fontsize = $this->FontSizePt;
19861: while ($write_block AND isset($dom[$nkey])) {
19862: if ($dom[$nkey]['tag']) {
19863: if ($dom[$nkey]['block']) {
19864:
19865: $write_block = false;
19866: }
19867: $tmp_fontname = isset($dom[$nkey]['fontname']) ? $dom[$nkey]['fontname'] : $this->FontFamily;
19868: $tmp_fontstyle = isset($dom[$nkey]['fontstyle']) ? $dom[$nkey]['fontstyle'] : $this->FontStyle;
19869: $tmp_fontsize = isset($dom[$nkey]['fontsize']) ? $dom[$nkey]['fontsize'] : $this->FontSizePt;
19870: } else {
19871: $nextstr = preg_split('/'.$this->re_space['p'].'+/'.$this->re_space['m'], $dom[$nkey]['value']);
19872: if (isset($nextstr[0])) {
19873: $wadj += $this->GetStringWidth($nextstr[0], $tmp_fontname, $tmp_fontstyle, $tmp_fontsize);
19874: ++$adjblks;
19875: }
19876: if (isset($nextstr[1])) {
19877: $write_block = false;
19878: }
19879: }
19880: ++$nkey;
19881: }
19882:
19883: if (($wadj > 0) AND (($this->rtl AND ($this->tmprtl == 'L')) OR (!$this->rtl AND ($this->tmprtl == 'R')))) {
19884:
19885: $reverse_dir = true;
19886: $this->rtl = !$this->rtl;
19887: $revshift = ($this->GetStringWidth($dom[$key]['value']) + $wadj) + 0.000001;
19888: if ($this->rtl) {
19889: $this->x += $revshift;
19890: } else {
19891: $this->x -= $revshift;
19892: }
19893: $xws = $this->x;
19894: }
19895:
19896: $strrest = $this->Write($this->lasth, $dom[$key]['value'], '', $wfill, '', false, 0, true, $firstblock, 0, $wadj);
19897:
19898: if ($reverse_dir AND ($wadj == 0)) {
19899: $this->x = $xws;
19900: $this->rtl = !$this->rtl;
19901: $reverse_dir = false;
19902: }
19903: }
19904: }
19905: $this->textindent = 0;
19906: if (strlen($strrest) > 0) {
19907:
19908: $this->newline = true;
19909: if ($strrest == $dom[$key]['value']) {
19910:
19911: ++$loop;
19912: } else {
19913: $loop = 0;
19914: }
19915: $dom[$key]['value'] = $strrest;
19916: if ($cell) {
19917: if ($this->rtl) {
19918: $this->x -= $this->cell_padding['R'];
19919: } else {
19920: $this->x += $this->cell_padding['L'];
19921: }
19922: }
19923: if ($loop < 3) {
19924: --$key;
19925: }
19926: } else {
19927: $loop = 0;
19928: }
19929: }
19930: ++$key;
19931: if (isset($dom[$key]['tag']) AND $dom[$key]['tag'] AND (!isset($dom[$key]['opening']) OR !$dom[$key]['opening']) AND isset($dom[($dom[$key]['parent'])]['attribute']['nobr']) AND ($dom[($dom[$key]['parent'])]['attribute']['nobr'] == 'true')) {
19932:
19933: if ((!$undo) AND ($this->y < $this->start_transaction_y)) {
19934:
19935:
19936: $this->rollbackTransaction(true);
19937:
19938: foreach ($this_method_vars as $vkey => $vval) {
19939: $$vkey = $vval;
19940: }
19941:
19942: $pre_y = $this->y;
19943: if ((!$this->checkPageBreak($this->PageBreakTrigger + 1)) AND ($this->y < $pre_y)) {
19944: $startliney = $this->y;
19945: }
19946: $undo = true;
19947: } else {
19948: $undo = false;
19949: }
19950: }
19951: }
19952:
19953: if (isset($startlinex)) {
19954: $yshift = $minstartliney - $startliney;
19955: if (($yshift > 0) OR ($this->page > $startlinepage)) {
19956: $yshift = 0;
19957: }
19958: $t_x = 0;
19959:
19960: $linew = abs($this->endlinex - $startlinex);
19961: if ($this->inxobj) {
19962:
19963: $pstart = substr($this->xobjects[$this->xobjid]['outdata'], 0, $startlinepos);
19964: if (isset($opentagpos)) {
19965: $midpos = $opentagpos;
19966: } else {
19967: $midpos = 0;
19968: }
19969: if ($midpos > 0) {
19970: $pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos, ($midpos - $startlinepos));
19971: $pend = substr($this->xobjects[$this->xobjid]['outdata'], $midpos);
19972: } else {
19973: $pmid = substr($this->xobjects[$this->xobjid]['outdata'], $startlinepos);
19974: $pend = '';
19975: }
19976: } else {
19977: $pstart = substr($this->getPageBuffer($startlinepage), 0, $startlinepos);
19978: if (isset($opentagpos) AND isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
19979: $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
19980: $midpos = min($opentagpos, $this->footerpos[$startlinepage]);
19981: } elseif (isset($opentagpos)) {
19982: $midpos = $opentagpos;
19983: } elseif (isset($this->footerlen[$startlinepage]) AND (!$this->InFooter)) {
19984: $this->footerpos[$startlinepage] = $this->pagelen[$startlinepage] - $this->footerlen[$startlinepage];
19985: $midpos = $this->footerpos[$startlinepage];
19986: } else {
19987: $midpos = 0;
19988: }
19989: if ($midpos > 0) {
19990: $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos, ($midpos - $startlinepos));
19991: $pend = substr($this->getPageBuffer($startlinepage), $midpos);
19992: } else {
19993: $pmid = substr($this->getPageBuffer($startlinepage), $startlinepos);
19994: $pend = '';
19995: }
19996: }
19997: if ((isset($plalign) AND ((($plalign == 'C') OR (($plalign == 'R') AND (!$this->rtl)) OR (($plalign == 'L') AND ($this->rtl)))))) {
19998:
19999: $tw = $w;
20000: if ($this->lMargin != $prevlMargin) {
20001: $tw += ($prevlMargin - $this->lMargin);
20002: }
20003: if ($this->rMargin != $prevrMargin) {
20004: $tw += ($prevrMargin - $this->rMargin);
20005: }
20006: $one_space_width = $this->GetStringWidth(chr(32));
20007: $no = 0;
20008: if ($this->isRTLTextDir()) {
20009:
20010: $pos1 = $this->revstrpos($pmid, '[(');
20011: if ($pos1 > 0) {
20012: $pos1 = intval($pos1);
20013: if ($this->isUnicodeFont()) {
20014: $pos2 = intval($this->revstrpos($pmid, '[('.chr(0).chr(32)));
20015: $spacelen = 2;
20016: } else {
20017: $pos2 = intval($this->revstrpos($pmid, '[('.chr(32)));
20018: $spacelen = 1;
20019: }
20020: if ($pos1 == $pos2) {
20021: $pmid = substr($pmid, 0, ($pos1 + 2)).substr($pmid, ($pos1 + 2 + $spacelen));
20022: if (substr($pmid, $pos1, 4) == '[()]') {
20023: $linew -= $one_space_width;
20024: } elseif ($pos1 == strpos($pmid, '[(')) {
20025: $no = 1;
20026: }
20027: }
20028: }
20029: } else {
20030:
20031: $pos1 = $this->revstrpos($pmid, ')]');
20032: if ($pos1 > 0) {
20033: $pos1 = intval($pos1);
20034: if ($this->isUnicodeFont()) {
20035: $pos2 = intval($this->revstrpos($pmid, chr(0).chr(32).')]')) + 2;
20036: $spacelen = 2;
20037: } else {
20038: $pos2 = intval($this->revstrpos($pmid, chr(32).')]')) + 1;
20039: $spacelen = 1;
20040: }
20041: if ($pos1 == $pos2) {
20042: $pmid = substr($pmid, 0, ($pos1 - $spacelen)).substr($pmid, $pos1);
20043: $linew -= $one_space_width;
20044: }
20045: }
20046: }
20047: $mdiff = ($tw - $linew);
20048: if ($plalign == 'C') {
20049: if ($this->rtl) {
20050: $t_x = -($mdiff / 2);
20051: } else {
20052: $t_x = ($mdiff / 2);
20053: }
20054: } elseif ($plalign == 'R') {
20055:
20056: $t_x = $mdiff;
20057: } elseif ($plalign == 'L') {
20058:
20059: $t_x = -$mdiff;
20060: }
20061: }
20062: if (($t_x != 0) OR ($yshift < 0)) {
20063:
20064: $trx = sprintf('1 0 0 1 %.3F %.3F cm', ($t_x * $this->k), ($yshift * $this->k));
20065: $pstart .= "\nq\n".$trx."\n".$pmid."\nQ\n";
20066: $endlinepos = strlen($pstart);
20067: if ($this->inxobj) {
20068:
20069: $this->xobjects[$this->xobjid]['outdata'] = $pstart.$pend;
20070: foreach ($this->xobjects[$this->xobjid]['annotations'] as $pak => $pac) {
20071: if ($pak >= $pask) {
20072: $this->xobjects[$this->xobjid]['annotations'][$pak]['x'] += $t_x;
20073: $this->xobjects[$this->xobjid]['annotations'][$pak]['y'] -= $yshift;
20074: }
20075: }
20076: } else {
20077: $this->setPageBuffer($startlinepage, $pstart.$pend);
20078:
20079: if (isset($this->PageAnnots[$this->page])) {
20080: foreach ($this->PageAnnots[$this->page] as $pak => $pac) {
20081: if ($pak >= $pask) {
20082: $this->PageAnnots[$this->page][$pak]['x'] += $t_x;
20083: $this->PageAnnots[$this->page][$pak]['y'] -= $yshift;
20084: }
20085: }
20086: }
20087: }
20088: $this->y -= $yshift;
20089: }
20090: }
20091:
20092: $this->setGraphicVars($gvars);
20093: if ($this->num_columns > 1) {
20094: $this->selectColumn();
20095: } elseif ($this->page > $prevPage) {
20096: $this->lMargin = $this->pagedim[$this->page]['olm'];
20097: $this->rMargin = $this->pagedim[$this->page]['orm'];
20098: }
20099:
20100: $this->cell_height_ratio = $prev_cell_height_ratio;
20101: $this->listnum = $prev_listnum;
20102: $this->listordered = $prev_listordered;
20103: $this->listcount = $prev_listcount;
20104: $this->lispacer = $prev_lispacer;
20105: if ($ln AND (!($cell AND ($dom[$key-1]['value'] == 'table')))) {
20106: $this->Ln($this->lasth);
20107: if ($this->y < $maxbottomliney) {
20108: $this->y = $maxbottomliney;
20109: }
20110: }
20111: unset($dom);
20112: }
20113:
20114: 20115: 20116: 20117: 20118: 20119: 20120:
20121: protected function openHTMLTagHandler(&$dom, $key, $cell) {
20122: $tag = $dom[$key];
20123: $parent = $dom[($dom[$key]['parent'])];
20124: $firsttag = ($key == 1);
20125:
20126: if (isset($tag['dir'])) {
20127: $this->setTempRTL($tag['dir']);
20128: } else {
20129: $this->tmprtl = false;
20130: }
20131: if ($tag['block']) {
20132: $hbz = 0;
20133: $hb = 0;
20134:
20135: if (isset($this->tagvspaces[$tag['value']][0]['h']) AND ($this->tagvspaces[$tag['value']][0]['h'] >= 0)) {
20136: $cur_h = $this->tagvspaces[$tag['value']][0]['h'];
20137: } elseif (isset($tag['fontsize'])) {
20138: $cur_h = ($tag['fontsize'] / $this->k) * $this->cell_height_ratio;
20139: } else {
20140: $cur_h = $this->FontSize * $this->cell_height_ratio;
20141: }
20142: if (isset($this->tagvspaces[$tag['value']][0]['n'])) {
20143: $n = $this->tagvspaces[$tag['value']][0]['n'];
20144: } elseif (preg_match('/[h][0-9]/', $tag['value']) > 0) {
20145: $n = 0.6;
20146: } else {
20147: $n = 1;
20148: }
20149: $hb = ($n * $cur_h);
20150: if (($this->htmlvspace <= 0) AND ($n > 0)) {
20151: if (isset($parent['fontsize'])) {
20152: $hbz = (($parent['fontsize'] / $this->k) * $this->cell_height_ratio);
20153: } else {
20154: $hbz = $this->FontSize * $this->cell_height_ratio;
20155: }
20156: }
20157: }
20158:
20159: switch($tag['value']) {
20160: case 'table': {
20161: $cp = 0;
20162: $cs = 0;
20163: $dom[$key]['rowspans'] = array();
20164: if (!isset($dom[$key]['attribute']['nested']) OR ($dom[$key]['attribute']['nested'] != 'true')) {
20165:
20166: if (!$this->empty_string($dom[$key]['thead'])) {
20167:
20168: $this->thead = $dom[$key]['thead'];
20169: if (!isset($this->theadMargins) OR (empty($this->theadMargins))) {
20170: $this->theadMargins = array();
20171: $this->theadMargins['cell_padding'] = $this->cell_padding;
20172: $this->theadMargins['lmargin'] = $this->lMargin;
20173: $this->theadMargins['rmargin'] = $this->rMargin;
20174: $this->theadMargins['page'] = $this->page;
20175: }
20176: }
20177: }
20178:
20179: $dom[$key]['old_cell_padding'] = $this->cell_padding;
20180: if (isset($tag['attribute']['cellpadding'])) {
20181: $pad = $this->getHTMLUnitToUnits($tag['attribute']['cellpadding'], 1, 'px');
20182: $this->SetCellPadding($pad);
20183: }
20184: if (isset($tag['attribute']['cellspacing'])) {
20185: $cs = $this->getHTMLUnitToUnits($tag['attribute']['cellspacing'], 1, 'px');
20186: }
20187: $prev_y = $this->y;
20188: if ($this->checkPageBreak(((2 * $cp) + (2 * $cs) + $this->lasth), '', false) OR ($this->y < $prev_y)) {
20189: $this->inthead = true;
20190:
20191: $this->checkPageBreak($this->PageBreakTrigger + 1);
20192: }
20193: break;
20194: }
20195: case 'tr': {
20196:
20197: $dom[$key]['cellpos'] = array();
20198: break;
20199: }
20200: case 'hr': {
20201: if ((isset($tag['height'])) AND ($tag['height'] != '')) {
20202: $hrHeight = $this->getHTMLUnitToUnits($tag['height'], 1, 'px');
20203: } else {
20204: $hrHeight = $this->GetLineWidth();
20205: }
20206: $this->addHTMLVertSpace($hbz, ($hrHeight / 2), $cell, $firsttag);
20207: $x = $this->GetX();
20208: $y = $this->GetY();
20209: $wtmp = $this->w - $this->lMargin - $this->rMargin;
20210: if ($cell) {
20211: $wtmp -= ($this->cell_padding['L'] + $this->cell_padding['R']);
20212: }
20213: if ((isset($tag['width'])) AND ($tag['width'] != '')) {
20214: $hrWidth = $this->getHTMLUnitToUnits($tag['width'], $wtmp, 'px');
20215: } else {
20216: $hrWidth = $wtmp;
20217: }
20218: $prevlinewidth = $this->GetLineWidth();
20219: $this->SetLineWidth($hrHeight);
20220: $this->Line($x, $y, $x + $hrWidth, $y);
20221: $this->SetLineWidth($prevlinewidth);
20222: $this->addHTMLVertSpace(($hrHeight / 2), 0, $cell, !isset($dom[($key + 1)]));
20223: break;
20224: }
20225: case 'a': {
20226: if (array_key_exists('href', $tag['attribute'])) {
20227: $this->HREF['url'] = $tag['attribute']['href'];
20228: }
20229: break;
20230: }
20231: case 'img': {
20232: if (isset($tag['attribute']['src'])) {
20233:
20234: if (($tag['attribute']['src'][0] == '/') AND ($_SERVER['DOCUMENT_ROOT'] != '/')) {
20235: $findroot = strpos($tag['attribute']['src'], $_SERVER['DOCUMENT_ROOT']);
20236: if (($findroot === false) OR ($findroot > 1)) {
20237: $tag['attribute']['src'] = $_SERVER['DOCUMENT_ROOT'].$tag['attribute']['src'];
20238: }
20239: }
20240: $tag['attribute']['src'] = urldecode($tag['attribute']['src']);
20241: $type = $this->getImageFileType($tag['attribute']['src']);
20242: $testscrtype = @parse_url($tag['attribute']['src']);
20243: if (!isset($testscrtype['query']) OR empty($testscrtype['query'])) {
20244:
20245: $tag['attribute']['src'] = str_replace(K_PATH_URL, K_PATH_MAIN, $tag['attribute']['src']);
20246: }
20247: if (!isset($tag['width'])) {
20248: $tag['width'] = 0;
20249: }
20250: if (!isset($tag['height'])) {
20251: $tag['height'] = 0;
20252: }
20253:
20254:
20255:
20256: $tag['attribute']['align'] = 'bottom';
20257:
20258: switch($tag['attribute']['align']) {
20259: case 'top': {
20260: $align = 'T';
20261: break;
20262: }
20263: case 'middle': {
20264: $align = 'M';
20265: break;
20266: }
20267: case 'bottom': {
20268: $align = 'B';
20269: break;
20270: }
20271: default: {
20272: $align = 'B';
20273: break;
20274: }
20275: }
20276: $prevy = $this->y;
20277: $xpos = $this->x;
20278:
20279: if (isset($dom[($key - 1)])) {
20280: if (($dom[($key - 1)]['value'] == ' ') OR (isset($dom[($key - 1)]['trimmed_space']))) {
20281: $xpos -= $this->GetStringWidth(chr(32));
20282: } elseif ($this->rtl AND $dom[($key - 1)]['value'] == ' ') {
20283: $xpos += (2 * $this->GetStringWidth(chr(32)));
20284: }
20285: }
20286: $imglink = '';
20287: if (isset($this->HREF['url']) AND !$this->empty_string($this->HREF['url'])) {
20288: $imglink = $this->HREF['url'];
20289: if ($imglink{0} == '#') {
20290:
20291: $lnkdata = explode(',', $imglink);
20292: if (isset($lnkdata[0])) {
20293: $page = intval(substr($lnkdata[0], 1));
20294: if (empty($page) OR ($page <= 0)) {
20295: $page = $this->page;
20296: }
20297: if (isset($lnkdata[1]) AND (strlen($lnkdata[1]) > 0)) {
20298: $lnky = floatval($lnkdata[1]);
20299: } else {
20300: $lnky = 0;
20301: }
20302: $imglink = $this->AddLink();
20303: $this->SetLink($imglink, $lnky, $page);
20304: }
20305: }
20306: }
20307: $border = 0;
20308: if (isset($tag['border']) AND !empty($tag['border'])) {
20309:
20310: $border = $tag['border'];
20311: }
20312: $iw = '';
20313: if (isset($tag['width'])) {
20314: $iw = $this->getHTMLUnitToUnits($tag['width'], 1, 'px', false);
20315: }
20316: $ih = '';
20317: if (isset($tag['height'])) {
20318: $ih = $this->getHTMLUnitToUnits($tag['height'], 1, 'px', false);
20319: }
20320: if (($type == 'eps') OR ($type == 'ai')) {
20321: $this->ImageEps($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, $imglink, true, $align, '', $border, true);
20322: } elseif ($type == 'svg') {
20323: $this->ImageSVG($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, $imglink, $align, '', $border, true);
20324: } else {
20325: $this->Image($tag['attribute']['src'], $xpos, $this->y, $iw, $ih, '', $imglink, $align, false, 300, '', false, false, $border, false, false, true);
20326: }
20327: switch($align) {
20328: case 'T': {
20329: $this->y = $prevy;
20330: break;
20331: }
20332: case 'M': {
20333: $this->y = (($this->img_rb_y + $prevy - ($tag['fontsize'] / $this->k)) / 2) ;
20334: break;
20335: }
20336: case 'B': {
20337: $this->y = $this->img_rb_y - ($tag['fontsize'] / $this->k);
20338: break;
20339: }
20340: }
20341: }
20342: break;
20343: }
20344: case 'dl': {
20345: ++$this->listnum;
20346: if ($this->listnum == 1) {
20347: $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
20348: } else {
20349: $this->addHTMLVertSpace(0, 0, $cell, $firsttag);
20350: }
20351: break;
20352: }
20353: case 'dt': {
20354: $this->addHTMLVertSpace($hbz, 0, $cell, $firsttag);
20355: break;
20356: }
20357: case 'dd': {
20358: if ($this->rtl) {
20359: $this->rMargin += $this->listindent;
20360: } else {
20361: $this->lMargin += $this->listindent;
20362: }
20363: ++$this->listindentlevel;
20364: $this->addHTMLVertSpace($hbz, 0, $cell, $firsttag);
20365: break;
20366: }
20367: case 'ul':
20368: case 'ol': {
20369: ++$this->listnum;
20370: if ($tag['value'] == 'ol') {
20371: $this->listordered[$this->listnum] = true;
20372: } else {
20373: $this->listordered[$this->listnum] = false;
20374: }
20375: if (isset($tag['attribute']['start'])) {
20376: $this->listcount[$this->listnum] = intval($tag['attribute']['start']) - 1;
20377: } else {
20378: $this->listcount[$this->listnum] = 0;
20379: }
20380: if ($this->rtl) {
20381: $this->rMargin += $this->listindent;
20382: $this->x -= $this->listindent;
20383: } else {
20384: $this->lMargin += $this->listindent;
20385: $this->x += $this->listindent;
20386: }
20387: ++$this->listindentlevel;
20388: if ($this->listnum == 1) {
20389: $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
20390: } else {
20391: $this->addHTMLVertSpace(0, 0, $cell, $firsttag);
20392: }
20393: break;
20394: }
20395: case 'li': {
20396: $this->addHTMLVertSpace($hbz, 0, $cell, $firsttag);
20397: if ($this->listordered[$this->listnum]) {
20398:
20399: if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) {
20400: $this->lispacer = $parent['attribute']['type'];
20401: } elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) {
20402: $this->lispacer = $parent['listtype'];
20403: } elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) {
20404: $this->lispacer = $this->lisymbol;
20405: } else {
20406: $this->lispacer = '#';
20407: }
20408: ++$this->listcount[$this->listnum];
20409: if (isset($tag['attribute']['value'])) {
20410: $this->listcount[$this->listnum] = intval($tag['attribute']['value']);
20411: }
20412: } else {
20413:
20414: if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) {
20415: $this->lispacer = $parent['attribute']['type'];
20416: } elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) {
20417: $this->lispacer = $parent['listtype'];
20418: } elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) {
20419: $this->lispacer = $this->lisymbol;
20420: } else {
20421: $this->lispacer = '!';
20422: }
20423: }
20424: break;
20425: }
20426: case 'blockquote': {
20427: if ($this->rtl) {
20428: $this->rMargin += $this->listindent;
20429: } else {
20430: $this->lMargin += $this->listindent;
20431: }
20432: ++$this->listindentlevel;
20433: $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
20434: break;
20435: }
20436: case 'br': {
20437: $this->addHTMLVertSpace($hbz, 0, $cell, $firsttag);
20438: break;
20439: }
20440: case 'div': {
20441: $this->addHTMLVertSpace($hbz, 0, $cell, $firsttag);
20442: break;
20443: }
20444: case 'p': {
20445: $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
20446: break;
20447: }
20448: case 'pre': {
20449: $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
20450: $this->premode = true;
20451: break;
20452: }
20453: case 'sup': {
20454: $this->SetXY($this->GetX(), $this->GetY() - ((0.7 * $this->FontSizePt) / $this->k));
20455: break;
20456: }
20457: case 'sub': {
20458: $this->SetXY($this->GetX(), $this->GetY() + ((0.3 * $this->FontSizePt) / $this->k));
20459: break;
20460: }
20461: case 'h1':
20462: case 'h2':
20463: case 'h3':
20464: case 'h4':
20465: case 'h5':
20466: case 'h6': {
20467: $this->addHTMLVertSpace($hbz, $hb, $cell, $firsttag);
20468: break;
20469: }
20470:
20471: case 'form': {
20472: if (isset($tag['attribute']['action'])) {
20473: $this->form_action = $tag['attribute']['action'];
20474: } else {
20475: $this->form_action = K_PATH_URL.$_SERVER['SCRIPT_NAME'];
20476: }
20477: if (isset($tag['attribute']['enctype'])) {
20478: $this->form_enctype = $tag['attribute']['enctype'];
20479: } else {
20480: $this->form_enctype = 'application/x-www-form-urlencoded';
20481: }
20482: if (isset($tag['attribute']['method'])) {
20483: $this->form_mode = $tag['attribute']['method'];
20484: } else {
20485: $this->form_mode = 'post';
20486: }
20487: break;
20488: }
20489: case 'input': {
20490: if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) {
20491: $name = $tag['attribute']['name'];
20492: } else {
20493: break;
20494: }
20495: $prop = array();
20496: $opt = array();
20497: if (isset($tag['attribute']['readonly']) AND !$this->empty_string($tag['attribute']['readonly'])) {
20498: $prop['readonly'] = true;
20499: }
20500: if (isset($tag['attribute']['value']) AND !$this->empty_string($tag['attribute']['value'])) {
20501: $value = $tag['attribute']['value'];
20502: }
20503: if (isset($tag['attribute']['maxlength']) AND !$this->empty_string($tag['attribute']['maxlength'])) {
20504: $opt['maxlen'] = intval($tag['attribute']['value']);
20505: }
20506: $h = $this->FontSize * $this->cell_height_ratio;
20507: if (isset($tag['attribute']['size']) AND !$this->empty_string($tag['attribute']['size'])) {
20508: $w = intval($tag['attribute']['size']) * $this->GetStringWidth(chr(32)) * 2;
20509: } else {
20510: $w = $h;
20511: }
20512: if (isset($tag['attribute']['checked']) AND (($tag['attribute']['checked'] == 'checked') OR ($tag['attribute']['checked'] == 'true'))) {
20513: $checked = true;
20514: } else {
20515: $checked = false;
20516: }
20517: switch ($tag['attribute']['type']) {
20518: case 'text': {
20519: if (isset($value)) {
20520: $opt['v'] = $value;
20521: }
20522: $this->TextField($name, $w, $h, $prop, $opt, '', '', false);
20523: break;
20524: }
20525: case 'password': {
20526: if (isset($value)) {
20527: $opt['v'] = $value;
20528: }
20529: $prop['password'] = 'true';
20530: $this->TextField($name, $w, $h, $prop, $opt, '', '', false);
20531: break;
20532: }
20533: case 'checkbox': {
20534: $this->CheckBox($name, $w, $checked, $prop, $opt, $value, '', '', false);
20535: break;
20536: }
20537: case 'radio': {
20538: $this->RadioButton($name, $w, $prop, $opt, $value, $checked, '', '', false);
20539: break;
20540: }
20541: case 'submit': {
20542: $w = $this->GetStringWidth($value) * 1.5;
20543: $h *= 1.6;
20544: $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
20545: $action = array();
20546: $action['S'] = 'SubmitForm';
20547: $action['F'] = $this->form_action;
20548: if ($this->form_enctype != 'FDF') {
20549: $action['Flags'] = array('ExportFormat');
20550: }
20551: if ($this->form_mode == 'get') {
20552: $action['Flags'] = array('GetMethod');
20553: }
20554: $this->Button($name, $w, $h, $value, $action, $prop, $opt, '', '', false);
20555: break;
20556: }
20557: case 'reset': {
20558: $w = $this->GetStringWidth($value) * 1.5;
20559: $h *= 1.6;
20560: $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
20561: $this->Button($name, $w, $h, $value, array('S'=>'ResetForm'), $prop, $opt, '', '', false);
20562: break;
20563: }
20564: case 'file': {
20565: $prop['fileSelect'] = 'true';
20566: $this->TextField($name, $w, $h, $prop, $opt, '', '', false);
20567: if (!isset($value)) {
20568: $value = '*';
20569: }
20570: $w = $this->GetStringWidth($value) * 2;
20571: $h *= 1.2;
20572: $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
20573: $jsaction = 'var f=this.getField(\''.$name.'\'); f.browseForFileToSubmit();';
20574: $this->Button('FB_'.$name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false);
20575: break;
20576: }
20577: case 'hidden': {
20578: if (isset($value)) {
20579: $opt['v'] = $value;
20580: }
20581: $opt['f'] = array('invisible', 'hidden');
20582: $this->TextField($name, 0, 0, $prop, $opt, '', '', false);
20583: break;
20584: }
20585: case 'image': {
20586:
20587: if (isset($tag['attribute']['src']) AND !$this->empty_string($tag['attribute']['src'])) {
20588: $img = $tag['attribute']['src'];
20589: } else {
20590: break;
20591: }
20592: $value = 'img';
20593:
20594: if (isset($tag['attribute']['onclick']) AND !empty($tag['attribute']['onclick'])) {
20595: $jsaction = $tag['attribute']['onclick'];
20596: } else {
20597: $jsaction = '';
20598: }
20599: $this->Button($name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false);
20600: break;
20601: }
20602: case 'button': {
20603: $w = $this->GetStringWidth($value) * 1.5;
20604: $h *= 1.6;
20605: $prop = array('lineWidth'=>1, 'borderStyle'=>'beveled', 'fillColor'=>array(196, 196, 196), 'strokeColor'=>array(255, 255, 255));
20606: if (isset($tag['attribute']['onclick']) AND !empty($tag['attribute']['onclick'])) {
20607: $jsaction = $tag['attribute']['onclick'];
20608: } else {
20609: $jsaction = '';
20610: }
20611: $this->Button($name, $w, $h, $value, $jsaction, $prop, $opt, '', '', false);
20612: break;
20613: }
20614: }
20615: break;
20616: }
20617: case 'textarea': {
20618: $prop = array();
20619: $opt = array();
20620: if (isset($tag['attribute']['readonly']) AND !$this->empty_string($tag['attribute']['readonly'])) {
20621: $prop['readonly'] = true;
20622: }
20623: if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) {
20624: $name = $tag['attribute']['name'];
20625: } else {
20626: break;
20627: }
20628: if (isset($tag['attribute']['value']) AND !$this->empty_string($tag['attribute']['value'])) {
20629: $opt['v'] = $tag['attribute']['value'];
20630: }
20631: if (isset($tag['attribute']['cols']) AND !$this->empty_string($tag['attribute']['cols'])) {
20632: $w = intval($tag['attribute']['cols']) * $this->GetStringWidth(chr(32)) * 2;
20633: } else {
20634: $w = 40;
20635: }
20636: if (isset($tag['attribute']['rows']) AND !$this->empty_string($tag['attribute']['rows'])) {
20637: $h = intval($tag['attribute']['rows']) * $this->FontSize * $this->cell_height_ratio;
20638: } else {
20639: $h = 10;
20640: }
20641: $prop['multiline'] = 'true';
20642: $this->TextField($name, $w, $h, $prop, $opt, '', '', false);
20643: break;
20644: }
20645: case 'select': {
20646: $h = $this->FontSize * $this->cell_height_ratio;
20647: if (isset($tag['attribute']['size']) AND !$this->empty_string($tag['attribute']['size'])) {
20648: $h *= ($tag['attribute']['size'] + 1);
20649: }
20650: $prop = array();
20651: $opt = array();
20652: if (isset($tag['attribute']['name']) AND !$this->empty_string($tag['attribute']['name'])) {
20653: $name = $tag['attribute']['name'];
20654: } else {
20655: break;
20656: }
20657: $w = 0;
20658: if (isset($tag['attribute']['opt']) AND !$this->empty_string($tag['attribute']['opt'])) {
20659: $options = explode('#!NwL!#', $tag['attribute']['opt']);
20660: $values = array();
20661: foreach ($options as $val) {
20662: if (strpos($val, '#!TaB!#') !== false) {
20663: $opts = explode('#!TaB!#', $val);
20664: $values[] = $opts;
20665: $w = max($w, $this->GetStringWidth($opts[1]));
20666: } else {
20667: $values[] = $val;
20668: $w = max($w, $this->GetStringWidth($val));
20669: }
20670: }
20671: } else {
20672: break;
20673: }
20674: $w *= 2;
20675: if (isset($tag['attribute']['multiple']) AND ($tag['attribute']['multiple']='multiple')) {
20676: $prop['multipleSelection'] = 'true';
20677: $this->ListBox($name, $w, $h, $values, $prop, $opt, '', '', false);
20678: } else {
20679: $this->ComboBox($name, $w, $h, $values, $prop, $opt, '', '', false);
20680: }
20681: break;
20682: }
20683: case 'tcpdf': {
20684: if (defined('K_TCPDF_CALLS_IN_HTML') AND (K_TCPDF_CALLS_IN_HTML === true)) {
20685:
20686: if (isset($tag['attribute']['method'])) {
20687: $tcpdf_method = $tag['attribute']['method'];
20688: if (method_exists($this, $tcpdf_method)) {
20689: if (isset($tag['attribute']['params']) AND (!empty($tag['attribute']['params']))) {
20690: $params = unserialize(urldecode($tag['attribute']['params']));
20691: call_user_func_array(array($this, $tcpdf_method), $params);
20692: } else {
20693: $this->$tcpdf_method();
20694: }
20695: $this->newline = true;
20696: }
20697: }
20698: }
20699: break;
20700: }
20701: default: {
20702: break;
20703: }
20704: }
20705:
20706: $bordertags = array('blockquote','br','dd','dl','div','dt','h1','h2','h3','h4','h5','h6','hr','li','ol','p','pre','ul','tcpdf','table');
20707: if (in_array($tag['value'], $bordertags)) {
20708:
20709: $dom[$key]['borderposition'] = $this->getBorderStartPosition();
20710: }
20711: if ($dom[$key]['self'] AND isset($dom[$key]['attribute']['pagebreakafter'])) {
20712: $pba = $dom[$key]['attribute']['pagebreakafter'];
20713:
20714: if (($pba == 'true') OR ($pba == 'left') OR ($pba == 'right')) {
20715:
20716: $this->checkPageBreak($this->PageBreakTrigger + 1);
20717: }
20718: if ((($pba == 'left') AND (((!$this->rtl) AND (($this->page % 2) == 0)) OR (($this->rtl) AND (($this->page % 2) != 0))))
20719: OR (($pba == 'right') AND (((!$this->rtl) AND (($this->page % 2) != 0)) OR (($this->rtl) AND (($this->page % 2) == 0))))) {
20720:
20721: $this->checkPageBreak($this->PageBreakTrigger + 1);
20722: }
20723: }
20724: }
20725:
20726: 20727: 20728: 20729: 20730: 20731: 20732: 20733:
20734: protected function closeHTMLTagHandler(&$dom, $key, $cell, $maxbottomliney=0) {
20735: $tag = $dom[$key];
20736: $parent = $dom[($dom[$key]['parent'])];
20737: $lasttag = ((!isset($dom[($key + 1)])) OR ((!isset($dom[($key + 2)])) AND ($dom[($key + 1)]['value'] == 'marker')));
20738: $in_table_head = false;
20739:
20740: if ($this->rtl) {
20741: $xmax = $this->w;
20742: } else {
20743: $xmax = 0;
20744: }
20745: if ($tag['block']) {
20746: $hbz = 0;
20747: $hb = 0;
20748:
20749: if (isset($this->tagvspaces[$tag['value']][1]['h']) AND ($this->tagvspaces[$tag['value']][1]['h'] >= 0)) {
20750: $pre_h = $this->tagvspaces[$tag['value']][1]['h'];
20751: } elseif (isset($parent['fontsize'])) {
20752: $pre_h = (($parent['fontsize'] / $this->k) * $this->cell_height_ratio);
20753: } else {
20754: $pre_h = $this->FontSize * $this->cell_height_ratio;
20755: }
20756: if (isset($this->tagvspaces[$tag['value']][1]['n'])) {
20757: $n = $this->tagvspaces[$tag['value']][1]['n'];
20758: } elseif (preg_match('/[h][0-9]/', $tag['value']) > 0) {
20759: $n = 0.6;
20760: } else {
20761: $n = 1;
20762: }
20763: $hb = ($n * $pre_h);
20764: if ($this->y < $maxbottomliney) {
20765: $hbz = ($maxbottomliney - $this->y);
20766: }
20767: }
20768:
20769: switch($tag['value']) {
20770: case 'tr': {
20771: $table_el = $dom[($dom[$key]['parent'])]['parent'];
20772: if (!isset($parent['endy'])) {
20773: $dom[($dom[$key]['parent'])]['endy'] = $this->y;
20774: $parent['endy'] = $this->y;
20775: }
20776: if (!isset($parent['endpage'])) {
20777: $dom[($dom[$key]['parent'])]['endpage'] = $this->page;
20778: $parent['endpage'] = $this->page;
20779: }
20780: if (!isset($parent['endcolumn'])) {
20781: $dom[($dom[$key]['parent'])]['endcolumn'] = $this->current_column;
20782: $parent['endcolumn'] = $this->current_column;
20783: }
20784:
20785: if (isset($dom[$table_el]['rowspans'])) {
20786: foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
20787: $dom[$table_el]['rowspans'][$k]['rowspan'] -= 1;
20788: if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
20789: if (($dom[$table_el]['rowspans'][$k]['endpage'] == $parent['endpage']) AND ($dom[$table_el]['rowspans'][$k]['endcolumn'] == $parent['endcolumn'])) {
20790: $dom[($dom[$key]['parent'])]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $parent['endy']);
20791: } elseif (($dom[$table_el]['rowspans'][$k]['endpage'] > $parent['endpage']) OR ($dom[$table_el]['rowspans'][$k]['endcolumn'] > $parent['endcolumn'])) {
20792: $dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy'];
20793: $dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage'];
20794: $dom[($dom[$key]['parent'])]['endcolumn'] = $dom[$table_el]['rowspans'][$k]['endcolumn'];
20795: }
20796: }
20797: }
20798:
20799: foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
20800: if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
20801: $dom[$table_el]['rowspans'][$k]['endpage'] = max($dom[$table_el]['rowspans'][$k]['endpage'], $dom[($dom[$key]['parent'])]['endpage']);
20802: $dom[($dom[$key]['parent'])]['endpage'] = $dom[$table_el]['rowspans'][$k]['endpage'];
20803: $dom[$table_el]['rowspans'][$k]['endcolumn'] = max($dom[$table_el]['rowspans'][$k]['endcolumn'], $dom[($dom[$key]['parent'])]['endcolumn']);
20804: $dom[($dom[$key]['parent'])]['endcolumn'] = $dom[$table_el]['rowspans'][$k]['endcolumn'];
20805: $dom[$table_el]['rowspans'][$k]['endy'] = max($dom[$table_el]['rowspans'][$k]['endy'], $dom[($dom[$key]['parent'])]['endy']);
20806: $dom[($dom[$key]['parent'])]['endy'] = $dom[$table_el]['rowspans'][$k]['endy'];
20807: }
20808: }
20809:
20810: foreach ($dom[$table_el]['rowspans'] as $k => $trwsp) {
20811: if ($dom[$table_el]['rowspans'][$k]['rowspan'] == 0) {
20812: $dom[$table_el]['rowspans'][$k]['endpage'] = $dom[($dom[$key]['parent'])]['endpage'];
20813: $dom[$table_el]['rowspans'][$k]['endcolumn'] = $dom[($dom[$key]['parent'])]['endcolumn'];
20814: $dom[$table_el]['rowspans'][$k]['endy'] = $dom[($dom[$key]['parent'])]['endy'];
20815: }
20816: }
20817: }
20818: $this->setPage($dom[($dom[$key]['parent'])]['endpage']);
20819: if ($this->num_columns > 1) {
20820: $this->selectColumn($dom[($dom[$key]['parent'])]['endcolumn']);
20821: }
20822: $this->y = $dom[($dom[$key]['parent'])]['endy'];
20823: if (isset($dom[$table_el]['attribute']['cellspacing'])) {
20824: $cellspacing = $this->getHTMLUnitToUnits($dom[$table_el]['attribute']['cellspacing'], 1, 'px');
20825: $this->y += $cellspacing;
20826: }
20827: $this->Ln(0, $cell);
20828: if ($this->current_column == $parent['startcolumn']) {
20829: $this->x = $parent['startx'];
20830: }
20831:
20832: if ($this->page > $parent['startpage']) {
20833: if (($this->rtl) AND ($this->pagedim[$this->page]['orm'] != $this->pagedim[$parent['startpage']]['orm'])) {
20834: $this->x -= ($this->pagedim[$this->page]['orm'] - $this->pagedim[$parent['startpage']]['orm']);
20835: } elseif ((!$this->rtl) AND ($this->pagedim[$this->page]['olm'] != $this->pagedim[$parent['startpage']]['olm'])) {
20836: $this->x += ($this->pagedim[$this->page]['olm'] - $this->pagedim[$parent['startpage']]['olm']);
20837: }
20838: }
20839: break;
20840: }
20841: case 'tablehead':
20842:
20843: $in_table_head = true;
20844: $this->inthead = false;
20845: case 'table': {
20846: $table_el = $parent;
20847:
20848: if (isset($table_el['attribute']['border']) AND ($table_el['attribute']['border'] > 0)) {
20849:
20850: $border = array('LTRB' => array('width' => $this->getCSSBorderWidth($table_el['attribute']['border']), 'cap'=>'square', 'join'=>'miter', 'dash'=> 0, 'color'=>array(0,0,0)));
20851: } else {
20852: $border = 0;
20853: }
20854: $default_border = $border;
20855: if (isset($table_el['attribute']['cellspacing'])) {
20856: $cellspacing = $this->getHTMLUnitToUnits($table_el['attribute']['cellspacing'], 1, 'px');
20857: } else {
20858: $cellspacing = 0;
20859: }
20860:
20861: foreach ($dom[($dom[$key]['parent'])]['trids'] as $j => $trkey) {
20862:
20863: if (isset($dom[($dom[$key]['parent'])]['rowspans'])) {
20864: foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) {
20865: if ($trwsp['trid'] == $trkey) {
20866: $dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] -= 1;
20867: }
20868: if (isset($prevtrkey) AND ($trwsp['trid'] == $prevtrkey) AND ($trwsp['mrowspan'] >= 0)) {
20869: $dom[($dom[$key]['parent'])]['rowspans'][$k]['trid'] = $trkey;
20870: }
20871: }
20872: }
20873: if (isset($prevtrkey) AND ($dom[$trkey]['startpage'] > $dom[$prevtrkey]['endpage'])) {
20874: $pgendy = $this->pagedim[$dom[$prevtrkey]['endpage']]['hk'] - $this->pagedim[$dom[$prevtrkey]['endpage']]['bm'];
20875: $dom[$prevtrkey]['endy'] = $pgendy;
20876:
20877: if (isset($dom[($dom[$key]['parent'])]['rowspans'])) {
20878: foreach ($dom[($dom[$key]['parent'])]['rowspans'] as $k => $trwsp) {
20879: if (($trwsp['trid'] == $trkey) AND ($trwsp['mrowspan'] > 1) AND ($trwsp['endpage'] == $dom[$prevtrkey]['endpage'])) {
20880: $dom[($dom[$key]['parent'])]['rowspans'][$k]['endy'] = $pgendy;
20881: $dom[($dom[$key]['parent'])]['rowspans'][$k]['mrowspan'] = -1;
20882: }
20883: }
20884: }
20885: }
20886: $prevtrkey = $trkey;
20887: $table_el = $dom[($dom[$key]['parent'])];
20888: }
20889:
20890: unset($xmax);
20891: foreach ($table_el['trids'] as $j => $trkey) {
20892: $parent = $dom[$trkey];
20893: if (!isset($xmax)) {
20894: $xmax = $parent['cellpos'][(count($parent['cellpos']) - 1)]['endx'];
20895: }
20896:
20897: foreach ($parent['cellpos'] as $k => $cellpos) {
20898: if (isset($cellpos['rowspanid']) AND ($cellpos['rowspanid'] >= 0)) {
20899: $cellpos['startx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['startx'];
20900: $cellpos['endx'] = $table_el['rowspans'][($cellpos['rowspanid'])]['endx'];
20901: $endy = $table_el['rowspans'][($cellpos['rowspanid'])]['endy'];
20902: $startpage = $table_el['rowspans'][($cellpos['rowspanid'])]['startpage'];
20903: $endpage = $table_el['rowspans'][($cellpos['rowspanid'])]['endpage'];
20904: $startcolumn = $table_el['rowspans'][($cellpos['rowspanid'])]['startcolumn'];
20905: $endcolumn = $table_el['rowspans'][($cellpos['rowspanid'])]['endcolumn'];
20906: } else {
20907: $endy = $parent['endy'];
20908: $startpage = $parent['startpage'];
20909: $endpage = $parent['endpage'];
20910: $startcolumn = $parent['startcolumn'];
20911: $endcolumn = $parent['endcolumn'];
20912: }
20913: if ($this->num_columns == 0) {
20914: $this->num_columns = 1;
20915: }
20916: if (isset($cellpos['border'])) {
20917: $border = $cellpos['border'];
20918: }
20919: if (isset($cellpos['bgcolor']) AND ($cellpos['bgcolor']) !== false) {
20920: $this->SetFillColorArray($cellpos['bgcolor']);
20921: $fill = true;
20922: } else {
20923: $fill = false;
20924: }
20925: $x = $cellpos['startx'];
20926: $y = $parent['starty'];
20927: $starty = $y;
20928: $w = abs($cellpos['endx'] - $cellpos['startx']);
20929:
20930: $border_start = $this->getBorderMode($border, $position='start');
20931: $border_end = $this->getBorderMode($border, $position='end');
20932: $border_middle = $this->getBorderMode($border, $position='middle');
20933:
20934: for ($page = $startpage; $page <= $endpage; ++$page) {
20935: $ccode = '';
20936: $this->setPage($page);
20937: if ($this->num_columns < 2) {
20938:
20939: $this->x = $x;
20940: $this->y = $this->tMargin;
20941: }
20942:
20943: if ($page > $startpage) {
20944: if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) {
20945: $this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']);
20946: } elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) {
20947: $this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']);
20948: }
20949: }
20950: if ($startpage == $endpage) {
20951: $deltacol = 0;
20952: $deltath = 0;
20953: for ($column = $startcolumn; $column <= $endcolumn; ++$column) {
20954: $this->selectColumn($column);
20955: if ($startcolumn == $endcolumn) {
20956: $cborder = $border;
20957: $h = $endy - $parent['starty'];
20958: $this->y = $y;
20959: $this->x = $x;
20960: } elseif ($column == $startcolumn) {
20961: $cborder = $border_start;
20962: $this->y = $starty;
20963: $this->x = $x;
20964: $h = $this->h - $this->y - $this->bMargin;
20965: if ($this->rtl) {
20966: $deltacol = $this->x + $this->rMargin - $this->w;
20967: } else {
20968: $deltacol = $this->x - $this->lMargin;
20969: }
20970: } elseif ($column == $endcolumn) {
20971: $cborder = $border_end;
20972: if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
20973: $this->y = $this->columns[$column]['th']['\''.$page.'\''];
20974: }
20975: $this->x += $deltacol;
20976: $h = $endy - $this->y;
20977: } else {
20978: $cborder = $border_middle;
20979: if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
20980: $this->y = $this->columns[$column]['th']['\''.$page.'\''];
20981: }
20982: $this->x += $deltacol;
20983: $h = $this->h - $this->y - $this->bMargin;
20984: }
20985: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
20986: }
20987: } elseif ($page == $startpage) {
20988: $deltacol = 0;
20989: $deltath = 0;
20990: for ($column = $startcolumn; $column < $this->num_columns; ++$column) {
20991: $this->selectColumn($column);
20992: if ($column == $startcolumn) {
20993: $cborder = $border_start;
20994: $this->y = $starty;
20995: $this->x = $x;
20996: $h = $this->h - $this->y - $this->bMargin;
20997: if ($this->rtl) {
20998: $deltacol = $this->x + $this->rMargin - $this->w;
20999: } else {
21000: $deltacol = $this->x - $this->lMargin;
21001: }
21002: } else {
21003: $cborder = $border_middle;
21004: if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
21005: $this->y = $this->columns[$column]['th']['\''.$page.'\''];
21006: }
21007: $this->x += $deltacol;
21008: $h = $this->h - $this->y - $this->bMargin;
21009: }
21010: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
21011: }
21012: } elseif ($page == $endpage) {
21013: $deltacol = 0;
21014: $deltath = 0;
21015: for ($column = 0; $column <= $endcolumn; ++$column) {
21016: $this->selectColumn($column);
21017: if ($column == $endcolumn) {
21018: $cborder = $border_end;
21019: if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
21020: $this->y = $this->columns[$column]['th']['\''.$page.'\''];
21021: }
21022: $this->x += $deltacol;
21023: $h = $endy - $this->y;
21024: } else {
21025: $cborder = $border_middle;
21026: if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
21027: $this->y = $this->columns[$column]['th']['\''.$page.'\''];
21028: }
21029: $this->x += $deltacol;
21030: $h = $this->h - $this->y - $this->bMargin;
21031: }
21032: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
21033: }
21034: } else {
21035: $deltacol = 0;
21036: $deltath = 0;
21037: for ($column = 0; $column < $this->num_columns; ++$column) {
21038: $this->selectColumn($column);
21039: $cborder = $border_middle;
21040: if (isset($this->columns[$column]['th']['\''.$page.'\''])) {
21041: $this->y = $this->columns[$column]['th']['\''.$page.'\''];
21042: }
21043: $this->x += $deltacol;
21044: $h = $this->h - $this->y - $this->bMargin;
21045: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
21046: }
21047: }
21048: if ($cborder OR $fill) {
21049:
21050: if ($this->inxobj) {
21051:
21052: if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) {
21053: $pagemarkkey = key($this->xobjects[$this->xobjid]['transfmrk']);
21054: $pagemark = &$this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey];
21055: } else {
21056: $pagemark = &$this->xobjects[$this->xobjid]['intmrk'];
21057: }
21058: $pagebuff = $this->xobjects[$this->xobjid]['outdata'];
21059: $pstart = substr($pagebuff, 0, $pagemark);
21060: $pend = substr($pagebuff, $pagemark);
21061: $this->xobjects[$this->xobjid]['outdata'] = $pstart.$ccode.$pend;
21062: $pagemark += strlen($ccode);
21063: } else {
21064:
21065: if (end($this->transfmrk[$this->page]) !== false) {
21066: $pagemarkkey = key($this->transfmrk[$this->page]);
21067: $pagemark = &$this->transfmrk[$this->page][$pagemarkkey];
21068: } elseif ($this->InFooter) {
21069: $pagemark = &$this->footerpos[$this->page];
21070: } else {
21071: $pagemark = &$this->intmrk[$this->page];
21072: }
21073: $pagebuff = $this->getPageBuffer($this->page);
21074: $pstart = substr($pagebuff, 0, $pagemark);
21075: $pend = substr($pagebuff, $pagemark);
21076: $this->setPageBuffer($this->page, $pstart.$ccode.$pend);
21077: $pagemark += strlen($ccode);
21078: }
21079: }
21080: }
21081:
21082: $border = $default_border;
21083: }
21084: if (isset($table_el['attribute']['cellspacing'])) {
21085: $cellspacing = $this->getHTMLUnitToUnits($table_el['attribute']['cellspacing'], 1, 'px');
21086: $this->y += $cellspacing;
21087: }
21088: $this->Ln(0, $cell);
21089: $this->x = $parent['startx'];
21090: if ($endpage > $startpage) {
21091: if (($this->rtl) AND ($this->pagedim[$endpage]['orm'] != $this->pagedim[$startpage]['orm'])) {
21092: $this->x += ($this->pagedim[$endpage]['orm'] - $this->pagedim[$startpage]['orm']);
21093: } elseif ((!$this->rtl) AND ($this->pagedim[$endpage]['olm'] != $this->pagedim[$startpage]['olm'])) {
21094: $this->x += ($this->pagedim[$endpage]['olm'] - $this->pagedim[$startpage]['olm']);
21095: }
21096: }
21097: }
21098: if (!$in_table_head) {
21099: $this->cell_padding = $table_el['old_cell_padding'];
21100:
21101: $this->resetLastH();
21102: if (($this->page == ($this->numpages - 1)) AND ($this->pageopen[$this->numpages]) AND ($this->emptypagemrk[$this->numpages] == $this->pagelen[$this->numpages])) {
21103:
21104: $this->deletePage($this->numpages);
21105: }
21106: if (isset($this->theadMargins['top'])) {
21107:
21108: $this->tMargin = $this->theadMargins['top'];
21109: $this->pagedim[$this->page]['tm'] = $this->tMargin;
21110: }
21111: if (!isset($table_el['attribute']['nested']) OR ($table_el['attribute']['nested'] != 'true')) {
21112:
21113: $this->thead = '';
21114: $this->theadMargins = array();
21115: }
21116: }
21117: $parent = $table_el;
21118: break;
21119: }
21120: case 'a': {
21121: $this->HREF = '';
21122: break;
21123: }
21124: case 'sup': {
21125: $this->SetXY($this->GetX(), $this->GetY() + ((0.7 * $parent['fontsize']) / $this->k));
21126: break;
21127: }
21128: case 'sub': {
21129: $this->SetXY($this->GetX(), $this->GetY() - ((0.3 * $parent['fontsize'])/$this->k));
21130: break;
21131: }
21132: case 'div': {
21133: $this->addHTMLVertSpace($hbz, 0, $cell, false, $lasttag);
21134: break;
21135: }
21136: case 'blockquote': {
21137: if ($this->rtl) {
21138: $this->rMargin -= $this->listindent;
21139: } else {
21140: $this->lMargin -= $this->listindent;
21141: }
21142: --$this->listindentlevel;
21143: $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
21144: break;
21145: }
21146: case 'p': {
21147: $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
21148: break;
21149: }
21150: case 'pre': {
21151: $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
21152: $this->premode = false;
21153: break;
21154: }
21155: case 'dl': {
21156: --$this->listnum;
21157: if ($this->listnum <= 0) {
21158: $this->listnum = 0;
21159: $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
21160: } else {
21161: $this->addHTMLVertSpace(0, 0, $cell, false, $lasttag);
21162: }
21163: $this->resetLastH();
21164: break;
21165: }
21166: case 'dt': {
21167: $this->lispacer = '';
21168: $this->addHTMLVertSpace(0, 0, $cell, false, $lasttag);
21169: break;
21170: }
21171: case 'dd': {
21172: $this->lispacer = '';
21173: if ($this->rtl) {
21174: $this->rMargin -= $this->listindent;
21175: } else {
21176: $this->lMargin -= $this->listindent;
21177: }
21178: --$this->listindentlevel;
21179: $this->addHTMLVertSpace(0, 0, $cell, false, $lasttag);
21180: break;
21181: }
21182: case 'ul':
21183: case 'ol': {
21184: --$this->listnum;
21185: $this->lispacer = '';
21186: if ($this->rtl) {
21187: $this->rMargin -= $this->listindent;
21188: } else {
21189: $this->lMargin -= $this->listindent;
21190: }
21191: --$this->listindentlevel;
21192: if ($this->listnum <= 0) {
21193: $this->listnum = 0;
21194: $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
21195: } else {
21196: $this->addHTMLVertSpace(0, 0, $cell, false, $lasttag);
21197: }
21198: $this->resetLastH();
21199: break;
21200: }
21201: case 'li': {
21202: $this->lispacer = '';
21203: $this->addHTMLVertSpace(0, 0, $cell, false, $lasttag);
21204: break;
21205: }
21206: case 'h1':
21207: case 'h2':
21208: case 'h3':
21209: case 'h4':
21210: case 'h5':
21211: case 'h6': {
21212: $this->addHTMLVertSpace($hbz, $hb, $cell, false, $lasttag);
21213: break;
21214: }
21215:
21216: case 'form': {
21217: $this->form_action = '';
21218: $this->form_enctype = 'application/x-www-form-urlencoded';
21219: break;
21220: }
21221: default : {
21222: break;
21223: }
21224: }
21225:
21226: $this->drawHTMLTagBorder($parent, $xmax);
21227: if (isset($dom[($dom[$key]['parent'])]['attribute']['pagebreakafter'])) {
21228: $pba = $dom[($dom[$key]['parent'])]['attribute']['pagebreakafter'];
21229:
21230: if (($pba == 'true') OR ($pba == 'left') OR ($pba == 'right')) {
21231:
21232: $this->checkPageBreak($this->PageBreakTrigger + 1);
21233: }
21234: if ((($pba == 'left') AND (((!$this->rtl) AND (($this->page % 2) == 0)) OR (($this->rtl) AND (($this->page % 2) != 0))))
21235: OR (($pba == 'right') AND (((!$this->rtl) AND (($this->page % 2) != 0)) OR (($this->rtl) AND (($this->page % 2) == 0))))) {
21236:
21237: $this->checkPageBreak($this->PageBreakTrigger + 1);
21238: }
21239: }
21240: $this->tmprtl = false;
21241: }
21242:
21243: 21244: 21245: 21246: 21247: 21248: 21249: 21250: 21251:
21252: protected function addHTMLVertSpace($hbz=0, $hb=0, $cell=false, $firsttag=false, $lasttag=false) {
21253: if ($firsttag) {
21254: $this->Ln(0, $cell);
21255: $this->htmlvspace = 0;
21256: return;
21257: }
21258: if ($lasttag) {
21259: $this->Ln($hbz, $cell);
21260: $this->htmlvspace = 0;
21261: return;
21262: }
21263: if ($hb < $this->htmlvspace) {
21264: $hd = 0;
21265: } else {
21266: $hd = $hb - $this->htmlvspace;
21267: $this->htmlvspace = $hb;
21268: }
21269: $this->Ln(($hbz + $hd), $cell);
21270: }
21271:
21272: 21273: 21274: 21275: 21276: 21277:
21278: protected function getBorderStartPosition() {
21279: if ($this->rtl) {
21280: $xmax = $this->lMargin;
21281: } else {
21282: $xmax = $this->w - $this->rMargin;
21283: }
21284: return array('page' => $this->page, 'column' => $this->current_column, 'x' => $this->x, 'y' => $this->y, 'xmax' => $xmax);
21285: }
21286:
21287: 21288: 21289: 21290: 21291: 21292: 21293:
21294: protected function drawHTMLTagBorder($tag, $xmax) {
21295: if (!isset($tag['borderposition'])) {
21296:
21297: return;
21298: }
21299: $prev_x = $this->x;
21300: $prev_y = $this->y;
21301: $prev_lasth = $this->lasth;
21302: $border = 0;
21303: $fill = false;
21304: $this->lasth = 0;
21305: if (isset($tag['border']) AND !empty($tag['border'])) {
21306:
21307: $border = $tag['border'];
21308: if (!$this->empty_string($this->thead) AND (!$this->inthead)) {
21309:
21310: $border = $this->getBorderMode($border, $position='middle');
21311: }
21312: }
21313: if (isset($tag['bgcolor']) AND ($tag['bgcolor'] !== false)) {
21314:
21315: $old_bgcolor = $this->bgcolor;
21316: $this->SetFillColorArray($tag['bgcolor']);
21317: $fill = true;
21318: }
21319: if (!$border AND !$fill) {
21320:
21321: return;
21322: }
21323: if (isset($tag['attribute']['cellspacing'])) {
21324: $cellspacing = $this->getHTMLUnitToUnits($tag['attribute']['cellspacing'], 1, 'px');
21325: } else {
21326: $cellspacing = 0;
21327: }
21328: if (($tag['value'] != 'table') AND (is_array($border)) AND (!empty($border))) {
21329:
21330: $border['mode'] = 'ext';
21331: }
21332: if ($this->rtl) {
21333: if ($xmax >= $tag['borderposition']['x']) {
21334: $xmax = $tag['borderposition']['xmax'];
21335: }
21336: $w = ($tag['borderposition']['x'] - $xmax);
21337: } else {
21338: if ($xmax <= $tag['borderposition']['x']) {
21339: $xmax = $tag['borderposition']['xmax'];
21340: }
21341: $w = ($xmax - $tag['borderposition']['x']);
21342: }
21343: if ($w <= 0) {
21344: return;
21345: }
21346: $w += $cellspacing;
21347: $startpage = $tag['borderposition']['page'];
21348: $startcolumn = $tag['borderposition']['column'];
21349: $x = $tag['borderposition']['x'];
21350: $y = $tag['borderposition']['y'];
21351: $endpage = $this->page;
21352: $starty = $tag['borderposition']['y'] - $cellspacing;
21353: $currentY = $this->y;
21354: $this->x = $x;
21355:
21356: $endcolumn = $this->current_column;
21357: if ($this->num_columns == 0) {
21358: $this->num_columns = 1;
21359: }
21360:
21361: $border_start = $this->getBorderMode($border, $position='start');
21362: $border_end = $this->getBorderMode($border, $position='end');
21363: $border_middle = $this->getBorderMode($border, $position='middle');
21364:
21365: for ($page = $startpage; $page <= $endpage; ++$page) {
21366: $ccode = '';
21367: $this->setPage($page);
21368: if ($this->num_columns < 2) {
21369:
21370: $this->x = $x;
21371: $this->y = $this->tMargin;
21372: }
21373:
21374: if ($page > $startpage) {
21375: if (($this->rtl) AND ($this->pagedim[$page]['orm'] != $this->pagedim[$startpage]['orm'])) {
21376: $this->x -= ($this->pagedim[$page]['orm'] - $this->pagedim[$startpage]['orm']);
21377: } elseif ((!$this->rtl) AND ($this->pagedim[$page]['olm'] != $this->pagedim[$startpage]['olm'])) {
21378: $this->x += ($this->pagedim[$page]['olm'] - $this->pagedim[$startpage]['olm']);
21379: }
21380: }
21381: if ($startpage == $endpage) {
21382:
21383: for ($column = $startcolumn; $column <= $endcolumn; ++$column) {
21384: $this->selectColumn($column);
21385: if ($startcolumn == $endcolumn) {
21386: $cborder = $border;
21387: $h = ($currentY - $y) + $cellspacing;
21388: $this->y = $starty;
21389: } elseif ($column == $startcolumn) {
21390: $cborder = $border_start;
21391: $this->y = $starty;
21392: $h = $this->h - $this->y - $this->bMargin;
21393: } elseif ($column == $endcolumn) {
21394: $cborder = $border_end;
21395: $h = $currentY - $this->y;
21396: } else {
21397: $cborder = $border_middle;
21398: $h = $this->h - $this->y - $this->bMargin;
21399: }
21400: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
21401: }
21402: } elseif ($page == $startpage) {
21403: for ($column = $startcolumn; $column < $this->num_columns; ++$column) {
21404: $this->selectColumn($column);
21405: if ($column == $startcolumn) {
21406: $cborder = $border_start;
21407: $this->y = $starty;
21408: $h = $this->h - $this->y - $this->bMargin;
21409: } else {
21410: $cborder = $border_middle;
21411: $h = $this->h - $this->y - $this->bMargin;
21412: }
21413: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
21414: }
21415: } elseif ($page == $endpage) {
21416: for ($column = 0; $column <= $endcolumn; ++$column) {
21417: $this->selectColumn($column);
21418: if ($column == $endcolumn) {
21419:
21420: $cborder = $border_end;
21421: $h = $currentY - $this->y;
21422: } else {
21423:
21424: $cborder = $border_middle;
21425: $h = $this->h - $this->y - $this->bMargin;
21426: }
21427: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
21428: }
21429: } else {
21430: for ($column = 0; $column < $this->num_columns; ++$column) {
21431: $this->selectColumn($column);
21432: $cborder = $border_middle;
21433: $h = $this->h - $this->y - $this->bMargin;
21434: $ccode .= $this->getCellCode($w, $h, '', $cborder, 1, '', $fill, '', 0, true)."\n";
21435: }
21436: }
21437: if ($cborder OR $fill) {
21438:
21439: if ($this->inxobj) {
21440:
21441: if (end($this->xobjects[$this->xobjid]['transfmrk']) !== false) {
21442: $pagemarkkey = key($this->xobjects[$this->xobjid]['transfmrk']);
21443: $pagemark = &$this->xobjects[$this->xobjid]['transfmrk'][$pagemarkkey];
21444: } else {
21445: $pagemark = &$this->xobjects[$this->xobjid]['intmrk'];
21446: }
21447: $pagebuff = $this->xobjects[$this->xobjid]['outdata'];
21448: $pstart = substr($pagebuff, 0, $pagemark);
21449: $pend = substr($pagebuff, $pagemark);
21450: $this->xobjects[$this->xobjid]['outdata'] = $pstart.$ccode.$pend;
21451: $pagemark += strlen($ccode);
21452: } else {
21453: if (end($this->transfmrk[$this->page]) !== false) {
21454: $pagemarkkey = key($this->transfmrk[$this->page]);
21455: $pagemark = &$this->transfmrk[$this->page][$pagemarkkey];
21456: } elseif ($this->InFooter) {
21457: $pagemark = &$this->footerpos[$this->page];
21458: } else {
21459: $pagemark = &$this->intmrk[$this->page];
21460: }
21461: $pagebuff = $this->getPageBuffer($this->page);
21462: $pstart = substr($pagebuff, 0, $this->bordermrk[$this->page]);
21463: $pend = substr($pagebuff, $this->bordermrk[$this->page]);
21464: $this->setPageBuffer($this->page, $pstart.$ccode.$pend);
21465: $offsetlen = strlen($ccode);
21466: $this->bordermrk[$this->page] += $offsetlen;
21467: $this->cntmrk[$this->page] += $offsetlen;
21468: $pagemark += $offsetlen;
21469: }
21470: }
21471: }
21472: if (isset($old_bgcolor)) {
21473:
21474: $this->SetFillColorArray($old_bgcolor);
21475: }
21476:
21477: $this->x = $prev_x;
21478: $this->y = $prev_y;
21479: $this->lasth = $prev_lasth;
21480: }
21481:
21482: 21483: 21484: 21485: 21486: 21487:
21488: public function setLIsymbol($symbol='!') {
21489: $symbol = strtolower($symbol);
21490: switch ($symbol) {
21491: case '!' :
21492: case '#' :
21493: case 'disc' :
21494: case 'circle' :
21495: case 'square' :
21496: case '1':
21497: case 'decimal':
21498: case 'decimal-leading-zero':
21499: case 'i':
21500: case 'lower-roman':
21501: case 'I':
21502: case 'upper-roman':
21503: case 'a':
21504: case 'lower-alpha':
21505: case 'lower-latin':
21506: case 'A':
21507: case 'upper-alpha':
21508: case 'upper-latin':
21509: case 'lower-greek': {
21510: $this->lisymbol = $symbol;
21511: break;
21512: }
21513: default : {
21514: $this->lisymbol = '';
21515: }
21516: }
21517: }
21518:
21519: 21520: 21521: 21522: 21523: 21524: 21525: 21526:
21527: public function SetBooklet($booklet=true, $inner=-1, $outer=-1) {
21528: $this->booklet = $booklet;
21529: if ($inner >= 0) {
21530: $this->lMargin = $inner;
21531: }
21532: if ($outer >= 0) {
21533: $this->rMargin = $outer;
21534: }
21535: }
21536:
21537: 21538: 21539: 21540: 21541: 21542:
21543: protected function swapMargins($reverse=true) {
21544: if ($reverse) {
21545:
21546: $mtemp = $this->original_lMargin;
21547: $this->original_lMargin = $this->original_rMargin;
21548: $this->original_rMargin = $mtemp;
21549: $deltam = $this->original_lMargin - $this->original_rMargin;
21550: $this->lMargin += $deltam;
21551: $this->rMargin -= $deltam;
21552: }
21553: }
21554:
21555: 21556: 21557: 21558: 21559: 21560: 21561: 21562: 21563: 21564: 21565: 21566:
21567: public function setHtmlVSpace($tagvs) {
21568: $this->tagvspaces = $tagvs;
21569: }
21570:
21571: 21572: 21573: 21574: 21575: 21576:
21577: public function setListIndentWidth($width) {
21578: return $this->customlistindent = floatval($width);
21579: }
21580:
21581: 21582: 21583: 21584: 21585: 21586:
21587: public function setOpenCell($isopen) {
21588: $this->opencell = $isopen;
21589: }
21590:
21591: 21592: 21593: 21594: 21595: 21596: 21597:
21598: public function setHtmlLinksStyle($color=array(0,0,255), $fontstyle='U') {
21599: $this->htmlLinkColorArray = $color;
21600: $this->htmlLinkFontStyle = $fontstyle;
21601: }
21602:
21603: 21604: 21605: 21606: 21607: 21608: 21609: 21610: 21611: 21612:
21613: public function getHTMLUnitToUnits($htmlval, $refsize=1, $defaultunit='px', $points=false) {
21614: $supportedunits = array('%', 'em', 'ex', 'px', 'in', 'cm', 'mm', 'pc', 'pt');
21615: $retval = 0;
21616: $value = 0;
21617: $unit = 'px';
21618: $k = $this->k;
21619: if ($points) {
21620: $k = 1;
21621: }
21622: if (in_array($defaultunit, $supportedunits)) {
21623: $unit = $defaultunit;
21624: }
21625: if (is_numeric($htmlval)) {
21626: $value = floatval($htmlval);
21627: } elseif (preg_match('/([0-9\.\-\+]+)/', $htmlval, $mnum)) {
21628: $value = floatval($mnum[1]);
21629: if (preg_match('/([a-z%]+)/', $htmlval, $munit)) {
21630: if (in_array($munit[1], $supportedunits)) {
21631: $unit = $munit[1];
21632: }
21633: }
21634: }
21635: switch ($unit) {
21636:
21637: case '%': {
21638: $retval = (($value * $refsize) / 100);
21639: break;
21640: }
21641:
21642: case 'em': {
21643: $retval = ($value * $refsize);
21644: break;
21645: }
21646:
21647: case 'ex': {
21648: $retval = $value * ($refsize / 2);
21649: break;
21650: }
21651:
21652: case 'in': {
21653: $retval = ($value * $this->dpi) / $k;
21654: break;
21655: }
21656:
21657: case 'cm': {
21658: $retval = ($value / 2.54 * $this->dpi) / $k;
21659: break;
21660: }
21661:
21662: case 'mm': {
21663: $retval = ($value / 25.4 * $this->dpi) / $k;
21664: break;
21665: }
21666:
21667: case 'pc': {
21668: $retval = ($value * 12) / $k;
21669: break;
21670: }
21671:
21672: case 'pt': {
21673: $retval = $value / $k;
21674: break;
21675: }
21676:
21677: case 'px': {
21678: $retval = $this->pixelsToUnits($value);
21679: break;
21680: }
21681: }
21682: return $retval;
21683: }
21684:
21685: 21686: 21687: 21688: 21689: 21690: 21691:
21692: public function intToRoman($number) {
21693: $roman = '';
21694: while ($number >= 1000) {
21695: $roman .= 'M';
21696: $number -= 1000;
21697: }
21698: while ($number >= 900) {
21699: $roman .= 'CM';
21700: $number -= 900;
21701: }
21702: while ($number >= 500) {
21703: $roman .= 'D';
21704: $number -= 500;
21705: }
21706: while ($number >= 400) {
21707: $roman .= 'CD';
21708: $number -= 400;
21709: }
21710: while ($number >= 100) {
21711: $roman .= 'C';
21712: $number -= 100;
21713: }
21714: while ($number >= 90) {
21715: $roman .= 'XC';
21716: $number -= 90;
21717: }
21718: while ($number >= 50) {
21719: $roman .= 'L';
21720: $number -= 50;
21721: }
21722: while ($number >= 40) {
21723: $roman .= 'XL';
21724: $number -= 40;
21725: }
21726: while ($number >= 10) {
21727: $roman .= 'X';
21728: $number -= 10;
21729: }
21730: while ($number >= 9) {
21731: $roman .= 'IX';
21732: $number -= 9;
21733: }
21734: while ($number >= 5) {
21735: $roman .= 'V';
21736: $number -= 5;
21737: }
21738: while ($number >= 4) {
21739: $roman .= 'IV';
21740: $number -= 4;
21741: }
21742: while ($number >= 1) {
21743: $roman .= 'I';
21744: --$number;
21745: }
21746: return $roman;
21747: }
21748:
21749: 21750: 21751: 21752: 21753: 21754: 21755: 21756:
21757: protected function putHtmlListBullet($listdepth, $listtype='', $size=10) {
21758: $size /= $this->k;
21759: $fill = '';
21760: $color = $this->fgcolor;
21761: $width = 0;
21762: $textitem = '';
21763: $tmpx = $this->x;
21764: $lspace = $this->GetStringWidth(' ');
21765: if ($listtype == '^') {
21766:
21767: $this->lispacer = '';
21768: return;
21769: } elseif ($listtype == '!') {
21770:
21771: $deftypes = array('disc', 'circle', 'square');
21772: $listtype = $deftypes[($listdepth - 1) % 3];
21773: } elseif ($listtype == '#') {
21774:
21775: $listtype = 'decimal';
21776: }
21777: switch ($listtype) {
21778:
21779: case 'none': {
21780: break;
21781: }
21782: case 'disc': {
21783: $fill = 'F';
21784: }
21785: case 'circle': {
21786: $fill .= 'D';
21787: $r = $size / 6;
21788: $lspace += (2 * $r);
21789: if ($this->rtl) {
21790: $this->x += $lspace;
21791: } else {
21792: $this->x -= $lspace;
21793: }
21794: $this->Circle(($this->x + $r), ($this->y + ($this->lasth / 2)), $r, 0, 360, $fill, array('color'=>$color), $color, 8);
21795: break;
21796: }
21797: case 'square': {
21798: $l = $size / 3;
21799: $lspace += $l;
21800: if ($this->rtl) {;
21801: $this->x += $lspace;
21802: } else {
21803: $this->x -= $lspace;
21804: }
21805: $this->Rect($this->x, ($this->y + (($this->lasth - $l)/ 2)), $l, $l, 'F', array(), $color);
21806: break;
21807: }
21808:
21809:
21810:
21811: case '1':
21812: case 'decimal': {
21813: $textitem = $this->listcount[$this->listnum];
21814: break;
21815: }
21816: case 'decimal-leading-zero': {
21817: $textitem = sprintf('%02d', $this->listcount[$this->listnum]);
21818: break;
21819: }
21820: case 'i':
21821: case 'lower-roman': {
21822: $textitem = strtolower($this->intToRoman($this->listcount[$this->listnum]));
21823: break;
21824: }
21825: case 'I':
21826: case 'upper-roman': {
21827: $textitem = $this->intToRoman($this->listcount[$this->listnum]);
21828: break;
21829: }
21830: case 'a':
21831: case 'lower-alpha':
21832: case 'lower-latin': {
21833: $textitem = chr(97 + $this->listcount[$this->listnum] - 1);
21834: break;
21835: }
21836: case 'A':
21837: case 'upper-alpha':
21838: case 'upper-latin': {
21839: $textitem = chr(65 + $this->listcount[$this->listnum] - 1);
21840: break;
21841: }
21842: case 'lower-greek': {
21843: $textitem = $this->unichr(945 + $this->listcount[$this->listnum] - 1);
21844: break;
21845: }
21846: 21847: 21848: 21849: 21850: 21851: 21852: 21853: 21854: 21855: 21856: 21857: 21858: 21859: 21860: 21861: 21862: 21863: 21864: 21865: 21866: 21867: 21868: 21869: 21870: 21871: 21872:
21873: default: {
21874: $textitem = $this->listcount[$this->listnum];
21875: }
21876: }
21877: if (!$this->empty_string($textitem)) {
21878:
21879: if ($this->rtl) {
21880: $textitem = '.'.$textitem;
21881: } else {
21882: $textitem = $textitem.'.';
21883: }
21884: $lspace += $this->GetStringWidth($textitem);
21885: if ($this->rtl) {
21886: $this->x += $lspace;
21887: } else {
21888: $this->x -= $lspace;
21889: }
21890: $this->Write($this->lasth, $textitem, '', false, '', false, 0, false);
21891: }
21892: $this->x = $tmpx;
21893: $this->lispacer = '^';
21894: }
21895:
21896: 21897: 21898: 21899: 21900: 21901:
21902: protected function getGraphicVars() {
21903: $grapvars = array(
21904: 'FontFamily' => $this->FontFamily,
21905: 'FontStyle' => $this->FontStyle,
21906: 'FontSizePt' => $this->FontSizePt,
21907: 'rMargin' => $this->rMargin,
21908: 'lMargin' => $this->lMargin,
21909: 'cell_padding' => $this->cell_padding,
21910: 'cell_margin' => $this->cell_margin,
21911: 'LineWidth' => $this->LineWidth,
21912: 'linestyleWidth' => $this->linestyleWidth,
21913: 'linestyleCap' => $this->linestyleCap,
21914: 'linestyleJoin' => $this->linestyleJoin,
21915: 'linestyleDash' => $this->linestyleDash,
21916: 'textrendermode' => $this->textrendermode,
21917: 'textstrokewidth' => $this->textstrokewidth,
21918: 'DrawColor' => $this->DrawColor,
21919: 'FillColor' => $this->FillColor,
21920: 'TextColor' => $this->TextColor,
21921: 'ColorFlag' => $this->ColorFlag,
21922: 'bgcolor' => $this->bgcolor,
21923: 'fgcolor' => $this->fgcolor,
21924: 'htmlvspace' => $this->htmlvspace,
21925: 'listindent' => $this->listindent,
21926: 'listindentlevel' => $this->listindentlevel,
21927: 'listnum' => $this->listnum,
21928: 'listordered' => $this->listordered,
21929: 'listcount' => $this->listcount,
21930: 'lispacer' => $this->lispacer,
21931: 'cell_height_ratio' => $this->cell_height_ratio,
21932: 'font_stretching' => $this->font_stretching,
21933: 'font_spacing' => $this->font_spacing,
21934:
21935: 'lasth' => $this->lasth,
21936: 'tMargin' => $this->tMargin,
21937: 'bMargin' => $this->bMargin,
21938: 'AutoPageBreak' => $this->AutoPageBreak,
21939: 'PageBreakTrigger' => $this->PageBreakTrigger,
21940: 'x' => $this->x,
21941: 'y' => $this->y,
21942: 'w' => $this->w,
21943: 'h' => $this->h,
21944: 'wPt' => $this->wPt,
21945: 'hPt' => $this->hPt,
21946: 'fwPt' => $this->fwPt,
21947: 'fhPt' => $this->fhPt,
21948: 'page' => $this->page,
21949: 'current_column' => $this->current_column,
21950: 'num_columns' => $this->num_columns
21951: );
21952: return $grapvars;
21953: }
21954:
21955: 21956: 21957: 21958: 21959: 21960: 21961:
21962: protected function setGraphicVars($gvars, $extended=false) {
21963: $this->FontFamily = $gvars['FontFamily'];
21964: $this->FontStyle = $gvars['FontStyle'];
21965: $this->FontSizePt = $gvars['FontSizePt'];
21966: $this->rMargin = $gvars['rMargin'];
21967: $this->lMargin = $gvars['lMargin'];
21968: $this->cell_padding = $gvars['cell_padding'];
21969: $this->cell_margin = $gvars['cell_margin'];
21970: $this->LineWidth = $gvars['LineWidth'];
21971: $this->linestyleWidth = $gvars['linestyleWidth'];
21972: $this->linestyleCap = $gvars['linestyleCap'];
21973: $this->linestyleJoin = $gvars['linestyleJoin'];
21974: $this->linestyleDash = $gvars['linestyleDash'];
21975: $this->textrendermode = $gvars['textrendermode'];
21976: $this->textstrokewidth = $gvars['textstrokewidth'];
21977: $this->DrawColor = $gvars['DrawColor'];
21978: $this->FillColor = $gvars['FillColor'];
21979: $this->TextColor = $gvars['TextColor'];
21980: $this->ColorFlag = $gvars['ColorFlag'];
21981: $this->bgcolor = $gvars['bgcolor'];
21982: $this->fgcolor = $gvars['fgcolor'];
21983: $this->htmlvspace = $gvars['htmlvspace'];
21984: $this->listindent = $gvars['listindent'];
21985: $this->listindentlevel = $gvars['listindentlevel'];
21986: $this->listnum = $gvars['listnum'];
21987: $this->listordered = $gvars['listordered'];
21988: $this->listcount = $gvars['listcount'];
21989: $this->lispacer = $gvars['lispacer'];
21990: $this->cell_height_ratio = $gvars['cell_height_ratio'];
21991: $this->font_stretching = $gvars['font_stretching'];
21992: $this->font_spacing = $gvars['font_spacing'];
21993: if ($extended) {
21994:
21995: $this->lasth = $gvars['lasth'];
21996: $this->tMargin = $gvars['tMargin'];
21997: $this->bMargin = $gvars['bMargin'];
21998: $this->AutoPageBreak = $gvars['AutoPageBreak'];
21999: $this->PageBreakTrigger = $gvars['PageBreakTrigger'];
22000: $this->x = $gvars['x'];
22001: $this->y = $gvars['y'];
22002: $this->w = $gvars['w'];
22003: $this->h = $gvars['h'];
22004: $this->wPt = $gvars['wPt'];
22005: $this->hPt = $gvars['hPt'];
22006: $this->fwPt = $gvars['fwPt'];
22007: $this->fhPt = $gvars['fhPt'];
22008: $this->page = $gvars['page'];
22009: $this->current_column = $gvars['current_column'];
22010: $this->num_columns = $gvars['num_columns'];
22011: }
22012: $this->_out(''.$this->linestyleWidth.' '.$this->linestyleCap.' '.$this->linestyleJoin.' '.$this->linestyleDash.' '.$this->DrawColor.' '.$this->FillColor.'');
22013: if (!$this->empty_string($this->FontFamily)) {
22014: $this->SetFont($this->FontFamily, $this->FontStyle, $this->FontSizePt);
22015: }
22016: }
22017:
22018: 22019: 22020: 22021: 22022: 22023: 22024:
22025: protected function getObjFilename($name) {
22026: return tempnam(K_PATH_CACHE, $name.'_');
22027: }
22028:
22029: 22030: 22031: 22032: 22033: 22034: 22035: 22036:
22037: protected function writeDiskCache($filename, $data, $append=false) {
22038: if ($append) {
22039: $fmode = 'ab+';
22040: } else {
22041: $fmode = 'wb+';
22042: }
22043: $f = @fopen($filename, $fmode);
22044: if (!$f) {
22045: $this->Error('Unable to write cache file: '.$filename);
22046: } else {
22047: fwrite($f, $data);
22048: fclose($f);
22049: }
22050:
22051: if (!isset($this->cache_file_length['_'.$filename])) {
22052: $this->cache_file_length['_'.$filename] = strlen($data);
22053: } else {
22054: $this->cache_file_length['_'.$filename] += strlen($data);
22055: }
22056: }
22057:
22058: 22059: 22060: 22061: 22062: 22063: 22064:
22065: protected function readDiskCache($filename) {
22066: return file_get_contents($filename);
22067: }
22068:
22069: 22070: 22071: 22072: 22073: 22074:
22075: protected function setBuffer($data) {
22076: $this->bufferlen += strlen($data);
22077: if ($this->diskcache) {
22078: if (!isset($this->buffer) OR $this->empty_string($this->buffer)) {
22079: $this->buffer = $this->getObjFilename('buffer');
22080: }
22081: $this->writeDiskCache($this->buffer, $data, true);
22082: } else {
22083: $this->buffer .= $data;
22084: }
22085: }
22086:
22087: 22088: 22089: 22090: 22091: 22092:
22093: protected function replaceBuffer($data) {
22094: $this->bufferlen = strlen($data);
22095: if ($this->diskcache) {
22096: if (!isset($this->buffer) OR $this->empty_string($this->buffer)) {
22097: $this->buffer = $this->getObjFilename('buffer');
22098: }
22099: $this->writeDiskCache($this->buffer, $data, false);
22100: } else {
22101: $this->buffer = $data;
22102: }
22103: }
22104:
22105: 22106: 22107: 22108: 22109: 22110:
22111: protected function getBuffer() {
22112: if ($this->diskcache) {
22113: return $this->readDiskCache($this->buffer);
22114: } else {
22115: return $this->buffer;
22116: }
22117: }
22118:
22119: 22120: 22121: 22122: 22123: 22124: 22125: 22126:
22127: protected function setPageBuffer($page, $data, $append=false) {
22128: if ($this->diskcache) {
22129: if (!isset($this->pages[$page])) {
22130: $this->pages[$page] = $this->getObjFilename('page'.$page);
22131: }
22132: $this->writeDiskCache($this->pages[$page], $data, $append);
22133: } else {
22134: if ($append) {
22135: $this->pages[$page] .= $data;
22136: } else {
22137: $this->pages[$page] = $data;
22138: }
22139: }
22140: if ($append AND isset($this->pagelen[$page])) {
22141: $this->pagelen[$page] += strlen($data);
22142: } else {
22143: $this->pagelen[$page] = strlen($data);
22144: }
22145: }
22146:
22147: 22148: 22149: 22150: 22151: 22152: 22153:
22154: protected function getPageBuffer($page) {
22155: if ($this->diskcache) {
22156: return $this->readDiskCache($this->pages[$page]);
22157: } elseif (isset($this->pages[$page])) {
22158: return $this->pages[$page];
22159: }
22160: return false;
22161: }
22162:
22163: 22164: 22165: 22166: 22167: 22168: 22169:
22170: protected function setImageBuffer($image, $data) {
22171: if ($this->diskcache) {
22172: if (!isset($this->images[$image])) {
22173: $this->images[$image] = $this->getObjFilename('image'.$image);
22174: }
22175: $this->writeDiskCache($this->images[$image], serialize($data));
22176: } else {
22177: $this->images[$image] = $data;
22178: }
22179: if (!in_array($image, $this->imagekeys)) {
22180: $this->imagekeys[] = $image;
22181: ++$this->numimages;
22182: }
22183: }
22184:
22185: 22186: 22187: 22188: 22189: 22190: 22191: 22192:
22193: protected function setImageSubBuffer($image, $key, $data) {
22194: if (!isset($this->images[$image])) {
22195: $this->setImageBuffer($image, array());
22196: }
22197: if ($this->diskcache) {
22198: $tmpimg = $this->getImageBuffer($image);
22199: $tmpimg[$key] = $data;
22200: $this->writeDiskCache($this->images[$image], serialize($tmpimg));
22201: } else {
22202: $this->images[$image][$key] = $data;
22203: }
22204: }
22205:
22206: 22207: 22208: 22209: 22210: 22211: 22212:
22213: protected function getImageBuffer($image) {
22214: if ($this->diskcache AND isset($this->images[$image])) {
22215: return unserialize($this->readDiskCache($this->images[$image]));
22216: } elseif (isset($this->images[$image])) {
22217: return $this->images[$image];
22218: }
22219: return false;
22220: }
22221:
22222: 22223: 22224: 22225: 22226: 22227: 22228:
22229: protected function setFontBuffer($font, $data) {
22230: if ($this->diskcache) {
22231: if (!isset($this->fonts[$font])) {
22232: $this->fonts[$font] = $this->getObjFilename('font');
22233: }
22234: $this->writeDiskCache($this->fonts[$font], serialize($data));
22235: } else {
22236: $this->fonts[$font] = $data;
22237: }
22238: if (!in_array($font, $this->fontkeys)) {
22239: $this->fontkeys[] = $font;
22240:
22241: ++$this->n;
22242: $this->font_obj_ids[$font] = $this->n;
22243: $this->setFontSubBuffer($font, 'n', $this->n);
22244: }
22245: }
22246:
22247: 22248: 22249: 22250: 22251: 22252: 22253: 22254:
22255: protected function setFontSubBuffer($font, $key, $data) {
22256: if (!isset($this->fonts[$font])) {
22257: $this->setFontBuffer($font, array());
22258: }
22259: if ($this->diskcache) {
22260: $tmpfont = $this->getFontBuffer($font);
22261: $tmpfont[$key] = $data;
22262: $this->writeDiskCache($this->fonts[$font], serialize($tmpfont));
22263: } else {
22264: $this->fonts[$font][$key] = $data;
22265: }
22266: }
22267:
22268: 22269: 22270: 22271: 22272: 22273: 22274:
22275: protected function getFontBuffer($font) {
22276: if ($this->diskcache AND isset($this->fonts[$font])) {
22277: return unserialize($this->readDiskCache($this->fonts[$font]));
22278: } elseif (isset($this->fonts[$font])) {
22279: return $this->fonts[$font];
22280: }
22281: return false;
22282: }
22283:
22284: 22285: 22286: 22287: 22288: 22289: 22290: 22291:
22292: public function movePage($frompage, $topage) {
22293: if (($frompage > $this->numpages) OR ($frompage <= $topage)) {
22294: return false;
22295: }
22296: if ($frompage == $this->page) {
22297:
22298: $this->endPage();
22299: }
22300:
22301: $tmppage = $this->pages[$frompage];
22302: $tmppagedim = $this->pagedim[$frompage];
22303: $tmppagelen = $this->pagelen[$frompage];
22304: $tmpintmrk = $this->intmrk[$frompage];
22305: $tmpbordermrk = $this->bordermrk[$frompage];
22306: $tmpcntmrk = $this->cntmrk[$frompage];
22307: if (isset($this->footerpos[$frompage])) {
22308: $tmpfooterpos = $this->footerpos[$frompage];
22309: }
22310: if (isset($this->footerlen[$frompage])) {
22311: $tmpfooterlen = $this->footerlen[$frompage];
22312: }
22313: if (isset($this->transfmrk[$frompage])) {
22314: $tmptransfmrk = $this->transfmrk[$frompage];
22315: }
22316: if (isset($this->PageAnnots[$frompage])) {
22317: $tmpannots = $this->PageAnnots[$frompage];
22318: }
22319: if (isset($this->newpagegroup[$frompage])) {
22320: $tmpnewpagegroup = $this->newpagegroup[$frompage];
22321: }
22322: for ($i = $frompage; $i > $topage; --$i) {
22323: $j = $i - 1;
22324:
22325: $this->pages[$i] = $this->pages[$j];
22326: $this->pagedim[$i] = $this->pagedim[$j];
22327: $this->pagelen[$i] = $this->pagelen[$j];
22328: $this->intmrk[$i] = $this->intmrk[$j];
22329: $this->bordermrk[$i] = $this->bordermrk[$j];
22330: $this->cntmrk[$i] = $this->cntmrk[$j];
22331: if (isset($this->footerpos[$j])) {
22332: $this->footerpos[$i] = $this->footerpos[$j];
22333: } elseif (isset($this->footerpos[$i])) {
22334: unset($this->footerpos[$i]);
22335: }
22336: if (isset($this->footerlen[$j])) {
22337: $this->footerlen[$i] = $this->footerlen[$j];
22338: } elseif (isset($this->footerlen[$i])) {
22339: unset($this->footerlen[$i]);
22340: }
22341: if (isset($this->transfmrk[$j])) {
22342: $this->transfmrk[$i] = $this->transfmrk[$j];
22343: } elseif (isset($this->transfmrk[$i])) {
22344: unset($this->transfmrk[$i]);
22345: }
22346: if (isset($this->PageAnnots[$j])) {
22347: $this->PageAnnots[$i] = $this->PageAnnots[$j];
22348: } elseif (isset($this->PageAnnots[$i])) {
22349: unset($this->PageAnnots[$i]);
22350: }
22351: if (isset($this->newpagegroup[$j])) {
22352: $this->newpagegroup[$i] = $this->newpagegroup[$j];
22353: } elseif (isset($this->newpagegroup[$i])) {
22354: unset($this->newpagegroup[$i]);
22355: }
22356: }
22357: $this->pages[$topage] = $tmppage;
22358: $this->pagedim[$topage] = $tmppagedim;
22359: $this->pagelen[$topage] = $tmppagelen;
22360: $this->intmrk[$topage] = $tmpintmrk;
22361: $this->bordermrk[$topage] = $tmpbordermrk;
22362: $this->cntmrk[$topage] = $tmpcntmrk;
22363: if (isset($tmpfooterpos)) {
22364: $this->footerpos[$topage] = $tmpfooterpos;
22365: } elseif (isset($this->footerpos[$topage])) {
22366: unset($this->footerpos[$topage]);
22367: }
22368: if (isset($tmpfooterlen)) {
22369: $this->footerlen[$topage] = $tmpfooterlen;
22370: } elseif (isset($this->footerlen[$topage])) {
22371: unset($this->footerlen[$topage]);
22372: }
22373: if (isset($tmptransfmrk)) {
22374: $this->transfmrk[$topage] = $tmptransfmrk;
22375: } elseif (isset($this->transfmrk[$topage])) {
22376: unset($this->transfmrk[$topage]);
22377: }
22378: if (isset($tmpannots)) {
22379: $this->PageAnnots[$topage] = $tmpannots;
22380: } elseif (isset($this->PageAnnots[$topage])) {
22381: unset($this->PageAnnots[$topage]);
22382: }
22383: if (isset($tmpnewpagegroup)) {
22384: $this->newpagegroup[$topage] = $tmpnewpagegroup;
22385: } elseif (isset($this->newpagegroup[$topage])) {
22386: unset($this->newpagegroup[$topage]);
22387: }
22388:
22389: $tmpoutlines = $this->outlines;
22390: foreach ($tmpoutlines as $key => $outline) {
22391: if (($outline['p'] >= $topage) AND ($outline['p'] < $frompage)) {
22392: $this->outlines[$key]['p'] = $outline['p'] + 1;
22393: } elseif ($outline['p'] == $frompage) {
22394: $this->outlines[$key]['p'] = $topage;
22395: }
22396: }
22397:
22398: $tmplinks = $this->links;
22399: foreach ($tmplinks as $key => $link) {
22400: if (($link[0] >= $topage) AND ($link[0] < $frompage)) {
22401: $this->links[$key][0] = $link[0] + 1;
22402: } elseif ($link[0] == $frompage) {
22403: $this->links[$key][0] = $topage;
22404: }
22405: }
22406:
22407: $tmpjavascript = $this->javascript;
22408: global $jfrompage, $jtopage;
22409: $jfrompage = $frompage;
22410: $jtopage = $topage;
22411: $this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/',
22412: create_function('$matches', 'global $jfrompage, $jtopage;
22413: $pagenum = intval($matches[3]) + 1;
22414: if (($pagenum >= $jtopage) AND ($pagenum < $jfrompage)) {
22415: $newpage = ($pagenum + 1);
22416: } elseif ($pagenum == $jfrompage) {
22417: $newpage = $jtopage;
22418: } else {
22419: $newpage = $pagenum;
22420: }
22421: --$newpage;
22422: return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript);
22423:
22424: $this->lastPage(true);
22425: return true;
22426: }
22427:
22428: 22429: 22430: 22431: 22432: 22433: 22434:
22435: public function deletePage($page) {
22436: if (($page < 1) OR ($page > $this->numpages)) {
22437: return false;
22438: }
22439:
22440: unset($this->pages[$page]);
22441: unset($this->pagedim[$page]);
22442: unset($this->pagelen[$page]);
22443: unset($this->intmrk[$page]);
22444: unset($this->bordermrk[$page]);
22445: unset($this->cntmrk[$page]);
22446: if (isset($this->footerpos[$page])) {
22447: unset($this->footerpos[$page]);
22448: }
22449: if (isset($this->footerlen[$page])) {
22450: unset($this->footerlen[$page]);
22451: }
22452: if (isset($this->transfmrk[$page])) {
22453: unset($this->transfmrk[$page]);
22454: }
22455: if (isset($this->PageAnnots[$page])) {
22456: unset($this->PageAnnots[$page]);
22457: }
22458: if (isset($this->newpagegroup[$page])) {
22459: unset($this->newpagegroup[$page]);
22460: }
22461: if (isset($this->pageopen[$page])) {
22462: unset($this->pageopen[$page]);
22463: }
22464:
22465: for ($i = $page; $i < $this->numpages; ++$i) {
22466: $j = $i + 1;
22467:
22468: $this->pages[$i] = $this->pages[$j];
22469: $this->pagedim[$i] = $this->pagedim[$j];
22470: $this->pagelen[$i] = $this->pagelen[$j];
22471: $this->intmrk[$i] = $this->intmrk[$j];
22472: $this->bordermrk[$i] = $this->bordermrk[$j];
22473: $this->cntmrk[$i] = $this->cntmrk[$j];
22474: if (isset($this->footerpos[$j])) {
22475: $this->footerpos[$i] = $this->footerpos[$j];
22476: } elseif (isset($this->footerpos[$i])) {
22477: unset($this->footerpos[$i]);
22478: }
22479: if (isset($this->footerlen[$j])) {
22480: $this->footerlen[$i] = $this->footerlen[$j];
22481: } elseif (isset($this->footerlen[$i])) {
22482: unset($this->footerlen[$i]);
22483: }
22484: if (isset($this->transfmrk[$j])) {
22485: $this->transfmrk[$i] = $this->transfmrk[$j];
22486: } elseif (isset($this->transfmrk[$i])) {
22487: unset($this->transfmrk[$i]);
22488: }
22489: if (isset($this->PageAnnots[$j])) {
22490: $this->PageAnnots[$i] = $this->PageAnnots[$j];
22491: } elseif (isset($this->PageAnnots[$i])) {
22492: unset($this->PageAnnots[$i]);
22493: }
22494: if (isset($this->newpagegroup[$j])) {
22495: $this->newpagegroup[$i] = $this->newpagegroup[$j];
22496: } elseif (isset($this->newpagegroup[$i])) {
22497: unset($this->newpagegroup[$i]);
22498: }
22499: if (isset($this->pageopen[$j])) {
22500: $this->pageopen[$i] = $this->pageopen[$j];
22501: } elseif (isset($this->pageopen[$i])) {
22502: unset($this->pageopen[$i]);
22503: }
22504: }
22505:
22506: unset($this->pages[$this->numpages]);
22507: unset($this->pagedim[$this->numpages]);
22508: unset($this->pagelen[$this->numpages]);
22509: unset($this->intmrk[$this->numpages]);
22510: unset($this->bordermrk[$this->numpages]);
22511: unset($this->cntmrk[$this->numpages]);
22512: if (isset($this->footerpos[$this->numpages])) {
22513: unset($this->footerpos[$this->numpages]);
22514: }
22515: if (isset($this->footerlen[$this->numpages])) {
22516: unset($this->footerlen[$this->numpages]);
22517: }
22518: if (isset($this->transfmrk[$this->numpages])) {
22519: unset($this->transfmrk[$this->numpages]);
22520: }
22521: if (isset($this->PageAnnots[$this->numpages])) {
22522: unset($this->PageAnnots[$this->numpages]);
22523: }
22524: if (isset($this->newpagegroup[$this->numpages])) {
22525: unset($this->newpagegroup[$this->numpages]);
22526: }
22527: if (isset($this->pageopen[$this->numpages])) {
22528: unset($this->pageopen[$this->numpages]);
22529: }
22530: --$this->numpages;
22531: $this->page = $this->numpages;
22532:
22533: $tmpoutlines = $this->outlines;
22534: foreach ($tmpoutlines as $key => $outline) {
22535: if ($outline['p'] > $page) {
22536: $this->outlines[$key]['p'] = $outline['p'] - 1;
22537: } elseif ($outline['p'] == $page) {
22538: unset($this->outlines[$key]);
22539: }
22540: }
22541:
22542: $tmplinks = $this->links;
22543: foreach ($tmplinks as $key => $link) {
22544: if ($link[0] > $page) {
22545: $this->links[$key][0] = $link[0] - 1;
22546: } elseif ($link[0] == $page) {
22547: unset($this->links[$key]);
22548: }
22549: }
22550:
22551: $tmpjavascript = $this->javascript;
22552: global $jpage;
22553: $jpage = $page;
22554: $this->javascript = preg_replace_callback('/this\.addField\(\'([^\']*)\',\'([^\']*)\',([0-9]+)/',
22555: create_function('$matches', 'global $jpage;
22556: $pagenum = intval($matches[3]) + 1;
22557: if ($pagenum >= $jpage) {
22558: $newpage = ($pagenum - 1);
22559: } elseif ($pagenum == $jpage) {
22560: $newpage = 1;
22561: } else {
22562: $newpage = $pagenum;
22563: }
22564: --$newpage;
22565: return "this.addField(\'".$matches[1]."\',\'".$matches[2]."\',".$newpage."";'), $tmpjavascript);
22566:
22567: $this->lastPage(true);
22568: return true;
22569: }
22570:
22571: 22572: 22573: 22574: 22575: 22576: 22577:
22578: public function copyPage($page=0) {
22579: if ($page == 0) {
22580:
22581: $page = $this->page;
22582: }
22583: if (($page < 1) OR ($page > $this->numpages)) {
22584: return false;
22585: }
22586: if ($page == $this->page) {
22587:
22588: $this->endPage();
22589: }
22590:
22591: ++$this->numpages;
22592: $this->page = $this->numpages;
22593: $this->pages[$this->page] = $this->pages[$page];
22594: $this->pagedim[$this->page] = $this->pagedim[$page];
22595: $this->pagelen[$this->page] = $this->pagelen[$page];
22596: $this->intmrk[$this->page] = $this->intmrk[$page];
22597: $this->bordermrk[$this->page] = $this->bordermrk[$page];
22598: $this->cntmrk[$this->page] = $this->cntmrk[$page];
22599: $this->pageopen[$this->page] = false;
22600: if (isset($this->footerpos[$page])) {
22601: $this->footerpos[$this->page] = $this->footerpos[$page];
22602: }
22603: if (isset($this->footerlen[$page])) {
22604: $this->footerlen[$this->page] = $this->footerlen[$page];
22605: }
22606: if (isset($this->transfmrk[$page])) {
22607: $this->transfmrk[$this->page] = $this->transfmrk[$page];
22608: }
22609: if (isset($this->PageAnnots[$page])) {
22610: $this->PageAnnots[$this->page] = $this->PageAnnots[$page];
22611: }
22612: if (isset($this->newpagegroup[$page])) {
22613: $this->newpagegroup[$this->page] = $this->newpagegroup[$page];
22614: }
22615:
22616: $tmpoutlines = $this->outlines;
22617: foreach ($tmpoutlines as $key => $outline) {
22618: if ($outline['p'] == $page) {
22619: $this->outlines[] = array('t' => $outline['t'], 'l' => $outline['l'], 'y' => $outline['y'], 'p' => $this->page);
22620: }
22621: }
22622:
22623: $tmplinks = $this->links;
22624: foreach ($tmplinks as $key => $link) {
22625: if ($link[0] == $page) {
22626: $this->links[] = array($this->page, $link[1]);
22627: }
22628: }
22629:
22630: $this->lastPage(true);
22631: return true;
22632: }
22633:
22634: 22635: 22636: 22637: 22638: 22639: 22640: 22641: 22642: 22643: 22644: 22645: 22646: 22647:
22648: public function addTOC($page='', $numbersfont='', $filler='.', $toc_name='TOC') {
22649: $fontsize = $this->FontSizePt;
22650: $fontfamily = $this->FontFamily;
22651: $fontstyle = $this->FontStyle;
22652: $w = $this->w - $this->lMargin - $this->rMargin;
22653: $spacer = $this->GetStringWidth(chr(32)) * 4;
22654: $page_first = $this->getPage();
22655: $lmargin = $this->lMargin;
22656: $rmargin = $this->rMargin;
22657: $x_start = $this->GetX();
22658: $current_page = $this->page;
22659: $current_column = $this->current_column;
22660: if ($this->empty_string($numbersfont)) {
22661: $numbersfont = $this->default_monospaced_font;
22662: }
22663: if ($this->empty_string($filler)) {
22664: $filler = ' ';
22665: }
22666: if ($this->empty_string($page)) {
22667: $gap = ' ';
22668: } else {
22669: $gap = '';
22670: if ($page < 1) {
22671: $page = 1;
22672: }
22673: }
22674: foreach ($this->outlines as $key => $outline) {
22675: if ($this->rtl) {
22676: $aligntext = 'R';
22677: $alignnum = 'L';
22678: } else {
22679: $aligntext = 'L';
22680: $alignnum = 'R';
22681: }
22682: if ($outline['l'] == 0) {
22683: $this->SetFont($fontfamily, $fontstyle.'B', $fontsize);
22684: } else {
22685: $this->SetFont($fontfamily, $fontstyle, $fontsize - $outline['l']);
22686: }
22687:
22688: $this->checkPageBreak(($this->FontSize * $this->cell_height_ratio));
22689:
22690: if (($this->page == $current_page) AND ($this->current_column == $current_column)) {
22691: $this->lMargin = $lmargin;
22692: $this->rMargin = $rmargin;
22693: } else {
22694: if ($this->current_column != $current_column) {
22695: if ($this->rtl) {
22696: $x_start = $this->w - $this->columns[$this->current_column]['x'];
22697: } else {
22698: $x_start = $this->columns[$this->current_column]['x'];
22699: }
22700: }
22701: $lmargin = $this->lMargin;
22702: $rmargin = $this->rMargin;
22703: $current_page = $this->page;
22704: $current_column = $this->current_column;
22705: }
22706: $this->SetX($x_start);
22707: $indent = ($spacer * $outline['l']);
22708: if ($this->rtl) {
22709: $this->rMargin += $indent;
22710: $this->x -= $indent;
22711: } else {
22712: $this->lMargin += $indent;
22713: $this->x += $indent;
22714: }
22715: $link = $this->AddLink();
22716: $this->SetLink($link, $outline['y'], $outline['p']);
22717:
22718: $this->Write(0, $outline['t'], $link, 0, $aligntext, false, 0, false, false, 0);
22719: $this->SetFont($numbersfont, $fontstyle, $fontsize);
22720: if ($this->empty_string($page)) {
22721: $pagenum = $outline['p'];
22722: } else {
22723:
22724: $pagenum = '{#'.($outline['p']).'}';
22725: if ($this->isUnicodeFont()) {
22726: $pagenum = '{'.$pagenum.'}';
22727: }
22728: }
22729: $numwidth = $this->GetStringWidth($pagenum);
22730: if ($this->rtl) {
22731: $tw = $this->x - $this->lMargin;
22732: } else {
22733: $tw = $this->w - $this->rMargin - $this->x;
22734: }
22735: $fw = $tw - $numwidth - $this->GetStringWidth(chr(32));
22736: $numfills = floor($fw / $this->GetStringWidth($filler));
22737: if ($numfills > 0) {
22738: $rowfill = str_repeat($filler, $numfills);
22739: } else {
22740: $rowfill = '';
22741: }
22742: if ($this->rtl) {
22743: $pagenum = $pagenum.$gap.$rowfill.' ';
22744: } else {
22745: $pagenum = ' '.$rowfill.$gap.$pagenum;
22746: }
22747:
22748: $this->Cell($tw, 0, $pagenum, 0, 1, $alignnum, 0, $link, 0);
22749: }
22750: $page_last = $this->getPage();
22751: $numpages = $page_last - $page_first + 1;
22752: if (!$this->empty_string($page)) {
22753: for ($p = $page_first; $p <= $page_last; ++$p) {
22754:
22755: $temppage = $this->getPageBuffer($p);
22756: for ($n = 1; $n <= $this->numpages; ++$n) {
22757:
22758: $k = '{#'.$n.'}';
22759: $ku = '{'.$k.'}';
22760: $alias_a = $this->_escape($k);
22761: $alias_au = $this->_escape($ku);
22762: if ($this->isunicode) {
22763: $alias_b = $this->_escape($this->UTF8ToLatin1($k));
22764: $alias_bu = $this->_escape($this->UTF8ToLatin1($ku));
22765: $alias_c = $this->_escape($this->utf8StrRev($k, false, $this->tmprtl));
22766: $alias_cu = $this->_escape($this->utf8StrRev($ku, false, $this->tmprtl));
22767: }
22768: if ($n >= $page) {
22769: $np = $n + $numpages;
22770: } else {
22771: $np = $n;
22772: }
22773: $ns = $this->formatTOCPageNumber($np);
22774: $nu = $ns;
22775: $sdiff = strlen($k) - strlen($ns) - 1;
22776: $sdiffu = strlen($ku) - strlen($ns) - 1;
22777: $sfill = str_repeat($filler, $sdiff);
22778: $sfillu = str_repeat($filler, $sdiffu);
22779: if ($this->rtl) {
22780: $ns = $ns.' '.$sfill;
22781: $nu = $nu.' '.$sfillu;
22782: } else {
22783: $ns = $sfill.' '.$ns;
22784: $nu = $sfillu.' '.$nu;
22785: }
22786: $nu = $this->UTF8ToUTF16BE($nu, false);
22787: $temppage = str_replace($alias_au, $nu, $temppage);
22788: if ($this->isunicode) {
22789: $temppage = str_replace($alias_bu, $nu, $temppage);
22790: $temppage = str_replace($alias_cu, $nu, $temppage);
22791: $temppage = str_replace($alias_b, $ns, $temppage);
22792: $temppage = str_replace($alias_c, $ns, $temppage);
22793: }
22794: $temppage = str_replace($alias_a, $ns, $temppage);
22795: }
22796:
22797: $this->setPageBuffer($p, $temppage);
22798: }
22799:
22800: $this->Bookmark($toc_name, 0, 0, $page_first);
22801: for ($i = 0; $i < $numpages; ++$i) {
22802: $this->movePage($page_last, $page);
22803: }
22804: }
22805: }
22806:
22807: 22808: 22809: 22810: 22811: 22812: 22813: 22814: 22815: 22816: 22817: 22818: 22819:
22820: public function addHTMLTOC($page='', $toc_name='TOC', $templates=array(), $correct_align=true) {
22821: $prev_htmlLinkColorArray = $this->htmlLinkColorArray;
22822: $prev_htmlLinkFontStyle = $this->htmlLinkFontStyle;
22823:
22824: $this->htmlLinkColorArray = array();
22825: $this->htmlLinkFontStyle = '';
22826: $page_first = $this->getPage();
22827:
22828: $current_font = $this->FontFamily;
22829: foreach ($templates as $level => $html) {
22830: $dom = $this->getHtmlDomArray($html);
22831: foreach ($dom as $key => $value) {
22832: if ($value['value'] == '#TOC_PAGE_NUMBER#') {
22833: $this->SetFont($dom[($key - 1)]['fontname']);
22834: $templates['F'.$level] = $this->isUnicodeFont();
22835: }
22836: }
22837: }
22838: $this->SetFont($current_font);
22839: foreach ($this->outlines as $key => $outline) {
22840:
22841: $row = $templates[$outline['l']];
22842: if ($this->empty_string($page)) {
22843: $pagenum = $outline['p'];
22844: } else {
22845:
22846: $pagenum = '{#'.($outline['p']).'}';
22847: if ($templates['F'.$outline['l']]) {
22848: $pagenum = '{'.$pagenum.'}';
22849: }
22850: }
22851:
22852: $row = str_replace('#TOC_DESCRIPTION#', $outline['t'], $row);
22853: $row = str_replace('#TOC_PAGE_NUMBER#', $pagenum, $row);
22854:
22855: $row = '<a href="#'.$outline['p'].','.$outline['y'].'">'.$row.'</a>';
22856:
22857: $this->writeHTML($row, false, false, true, false, '');
22858: }
22859:
22860: $this->htmlLinkColorArray = $prev_htmlLinkColorArray;
22861: $this->htmlLinkFontStyle = $prev_htmlLinkFontStyle;
22862:
22863: $page_last = $this->getPage();
22864: $numpages = $page_last - $page_first + 1;
22865: if (!$this->empty_string($page)) {
22866: for ($p = $page_first; $p <= $page_last; ++$p) {
22867:
22868: $temppage = $this->getPageBuffer($p);
22869: for ($n = 1; $n <= $this->numpages; ++$n) {
22870:
22871: $k = '{#'.$n.'}';
22872: $ku = '{'.$k.'}';
22873: $alias_a = $this->_escape($k);
22874: $alias_au = $this->_escape('{'.$k.'}');
22875: if ($this->isunicode) {
22876: $alias_b = $this->_escape($this->UTF8ToLatin1($k));
22877: $alias_bu = $this->_escape($this->UTF8ToLatin1($ku));
22878: $alias_c = $this->_escape($this->utf8StrRev($k, false, $this->tmprtl));
22879: $alias_cu = $this->_escape($this->utf8StrRev($ku, false, $this->tmprtl));
22880: }
22881: if ($n >= $page) {
22882: $np = $n + $numpages;
22883: } else {
22884: $np = $n;
22885: }
22886: $ns = $this->formatTOCPageNumber($np);
22887: $nu = $ns;
22888: if ($correct_align) {
22889: $sdiff = strlen($k) - strlen($ns);
22890: $sdiffu = strlen($ku) - strlen($ns);
22891: $sfill = str_repeat(' ', $sdiff);
22892: $sfillu = str_repeat(' ', $sdiffu);
22893: if ($this->rtl) {
22894: $ns = $ns.$sfill;
22895: $nu = $nu.$sfillu;
22896: } else {
22897: $ns = $sfill.$ns;
22898: $nu = $sfillu.$nu;
22899: }
22900: }
22901: $nu = $this->UTF8ToUTF16BE($nu, false);
22902: $temppage = str_replace($alias_au, $nu, $temppage);
22903: if ($this->isunicode) {
22904: $temppage = str_replace($alias_bu, $nu, $temppage);
22905: $temppage = str_replace($alias_cu, $nu, $temppage);
22906: $temppage = str_replace($alias_b, $ns, $temppage);
22907: $temppage = str_replace($alias_c, $ns, $temppage);
22908: }
22909: $temppage = str_replace($alias_a, $ns, $temppage);
22910: }
22911:
22912: $this->setPageBuffer($p, $temppage);
22913: }
22914:
22915: $this->Bookmark($toc_name, 0, 0, $page_first);
22916: for ($i = 0; $i < $numpages; ++$i) {
22917: $this->movePage($page_last, $page);
22918: }
22919: }
22920: }
22921:
22922: 22923: 22924: 22925: 22926:
22927: public function startTransaction() {
22928: if (isset($this->objcopy)) {
22929:
22930: $this->commitTransaction();
22931: }
22932:
22933: $this->start_transaction_page = $this->page;
22934: $this->start_transaction_y = $this->y;
22935:
22936: $this->objcopy = $this->objclone($this);
22937: }
22938:
22939: 22940: 22941: 22942: 22943:
22944: public function commitTransaction() {
22945: if (isset($this->objcopy)) {
22946: $this->objcopy->_destroy(true, true);
22947: unset($this->objcopy);
22948: }
22949: }
22950:
22951: 22952: 22953: 22954: 22955: 22956: 22957:
22958: public function rollbackTransaction($self=false) {
22959: if (isset($this->objcopy)) {
22960: if (isset($this->objcopy->diskcache) AND $this->objcopy->diskcache) {
22961:
22962: foreach ($this->objcopy->cache_file_length as $file => $length) {
22963: $file = substr($file, 1);
22964: $handle = fopen($file, 'r+');
22965: ftruncate($handle, $length);
22966: }
22967: }
22968: $this->_destroy(true, true);
22969: if ($self) {
22970: $objvars = get_object_vars($this->objcopy);
22971: foreach ($objvars as $key => $value) {
22972: $this->$key = $value;
22973: }
22974: }
22975: return $this->objcopy;
22976: }
22977: return $this;
22978: }
22979:
22980: 22981: 22982: 22983: 22984: 22985: 22986:
22987: public function objclone($object) {
22988: return @clone($object);
22989: }
22990:
22991: 22992: 22993: 22994: 22995: 22996: 22997:
22998: public function empty_string($str) {
22999: return (is_null($str) OR (is_string($str) AND (strlen($str) == 0)));
23000: }
23001:
23002: 23003: 23004: 23005: 23006: 23007: 23008: 23009: 23010:
23011: public function revstrpos($haystack, $needle, $offset = 0) {
23012: $length = strlen($haystack);
23013: $offset = ($offset > 0)?($length - $offset):abs($offset);
23014: $pos = strpos(strrev($haystack), strrev($needle), $offset);
23015: return ($pos === false)?false:($length - $pos - strlen($needle));
23016: }
23017:
23018:
23019:
23020: 23021: 23022: 23023: 23024: 23025: 23026: 23027:
23028: public function setEqualColumns($numcols=0, $width=0, $y='') {
23029: $this->columns = array();
23030: if ($numcols < 2) {
23031: $numcols = 0;
23032: $this->columns = array();
23033: } else {
23034:
23035: $maxwidth = ($this->w - $this->original_lMargin - $this->original_rMargin) / $numcols;
23036: if (($width == 0) OR ($width > $maxwidth)) {
23037: $width = $maxwidth;
23038: }
23039: if ($this->empty_string($y)) {
23040: $y = $this->y;
23041: }
23042:
23043: $space = (($this->w - $this->original_lMargin - $this->original_rMargin - ($numcols * $width)) / ($numcols - 1));
23044:
23045: for ($i = 0; $i < $numcols; ++$i) {
23046: $this->columns[$i] = array('w' => $width, 's' => $space, 'y' => $y);
23047: }
23048: }
23049: $this->num_columns = $numcols;
23050: $this->current_column = 0;
23051: $this->column_start_page = $this->page;
23052: }
23053:
23054: 23055: 23056: 23057: 23058: 23059: 23060:
23061: public function setColumnsArray($columns) {
23062: $this->columns = $columns;
23063: $this->num_columns = count($columns);
23064: $this->current_column = 0;
23065: $this->column_start_page = $this->page;
23066: }
23067:
23068: 23069: 23070: 23071: 23072: 23073:
23074: public function selectColumn($col='') {
23075: if (is_string($col)) {
23076: $col = $this->current_column;
23077: } elseif($col >= $this->num_columns) {
23078: $col = 0;
23079: }
23080: $xshift = 0;
23081: $enable_thead = false;
23082: if ($this->num_columns > 1) {
23083: if ($col != $this->current_column) {
23084:
23085: if ($this->column_start_page == $this->page) {
23086: $this->y = $this->columns[$col]['y'];
23087: } else {
23088: $this->y = $this->tMargin;
23089: }
23090:
23091: if (($this->page > $this->maxselcol['page']) OR (($this->page == $this->maxselcol['page']) AND ($col > $this->maxselcol['column']))) {
23092: $enable_thead = true;
23093: $this->maxselcol['page'] = $this->page;
23094: $this->maxselcol['column'] = $col;
23095: }
23096: }
23097: $xshift = $this->colxshift;
23098:
23099: $listindent = ($this->listindentlevel * $this->listindent);
23100: $colpos = ($col * ($this->columns[$col]['w'] + $this->columns[$col]['s']));
23101: if ($this->rtl) {
23102: $x = $this->w - $this->original_rMargin - $colpos;
23103: $this->rMargin = ($this->w - $x + $listindent);
23104: $this->lMargin = ($x - $this->columns[$col]['w']);
23105: $this->x = $x - $listindent;
23106: } else {
23107: $x = $this->original_lMargin + $colpos;
23108: $this->lMargin = ($x + $listindent);
23109: $this->rMargin = ($this->w - $x - $this->columns[$col]['w']);
23110: $this->x = $x + $listindent;
23111: }
23112: $this->columns[$col]['x'] = $x;
23113: }
23114: $this->current_column = $col;
23115:
23116: $this->newline = true;
23117:
23118: if ((!$this->empty_string($this->thead)) AND (!$this->inthead)) {
23119: if ($enable_thead) {
23120:
23121: $this->writeHTML($this->thead, false, false, false, false, '');
23122: $this->y += $xshift['s'];
23123:
23124: if (!isset($this->columns[$col]['th'])) {
23125: $this->columns[$col]['th'] = array();
23126: }
23127: $this->columns[$col]['th']['\''.$this->page.'\''] = $this->y;
23128: $this->lasth = 0;
23129: } elseif (isset($this->columns[$col]['th']['\''.$this->page.'\''])) {
23130: $this->y = $this->columns[$col]['th']['\''.$this->page.'\''];
23131: }
23132: }
23133:
23134: if ($this->rtl) {
23135: $this->rMargin += $xshift['x'];
23136: $this->x -= ($xshift['x'] + $xshift['p']);
23137: } else {
23138: $this->lMargin += $xshift['x'];
23139: $this->x += $xshift['x'] + $xshift['p'];
23140: }
23141: }
23142:
23143: 23144: 23145: 23146: 23147: 23148:
23149: public function getColumn() {
23150: return $this->current_column;
23151: }
23152:
23153: 23154: 23155: 23156: 23157: 23158:
23159: public function getNumberOfColumns() {
23160: return $this->num_columns;
23161: }
23162:
23163: 23164: 23165: 23166: 23167: 23168: 23169:
23170: public function serializeTCPDFtagParameters($pararray) {
23171: return urlencode(serialize($pararray));
23172: }
23173:
23174: 23175: 23176: 23177: 23178: 23179: 23180: 23181:
23182: public function setTextRenderingMode($stroke=0, $fill=true, $clip=false) {
23183:
23184:
23185: if ($stroke < 0) {
23186: $stroke = 0;
23187: }
23188: if ($fill === true) {
23189: if ($stroke > 0) {
23190: if ($clip === true) {
23191:
23192: $textrendermode = 6;
23193: } else {
23194:
23195: $textrendermode = 2;
23196: }
23197: $textstrokewidth = $stroke;
23198: } else {
23199: if ($clip === true) {
23200:
23201: $textrendermode = 4;
23202: } else {
23203:
23204: $textrendermode = 0;
23205: }
23206: }
23207: } else {
23208: if ($stroke > 0) {
23209: if ($clip === true) {
23210:
23211: $textrendermode = 5;
23212: } else {
23213:
23214: $textrendermode = 1;
23215: }
23216: $textstrokewidth = $stroke;
23217: } else {
23218: if ($clip === true) {
23219:
23220: $textrendermode = 7;
23221: } else {
23222:
23223: $textrendermode = 3;
23224: }
23225: }
23226: }
23227: $this->textrendermode = $textrendermode;
23228: $this->textstrokewidth = $stroke * $this->k;
23229: }
23230:
23231: 23232: 23233: 23234: 23235: 23236: 23237: 23238: 23239: 23240: 23241: 23242: 23243: 23244:
23245: protected function hyphenateWord($word, $patterns, $dictionary=array(), $leftmin=1, $rightmin=2, $charmin=1, $charmax=8) {
23246: $hyphenword = array();
23247: $numchars = count($word);
23248: if ($numchars <= $charmin) {
23249: return $word;
23250: }
23251: $word_string = $this->UTF8ArrSubString($word);
23252:
23253: $pattern = '/^([a-zA-Z0-9_\.\-]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/';
23254: if (preg_match($pattern, $word_string) > 0) {
23255:
23256: return $word;
23257: }
23258: $pattern = '/(([a-zA-Z0-9\-]+\.)?)((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/';
23259: if (preg_match($pattern, $word_string) > 0) {
23260:
23261: return $word;
23262: }
23263: if (isset($dictionary[$word_string])) {
23264: return $this->UTF8StringToArray($dictionary[$word_string]);
23265: }
23266:
23267: $tmpword = array_merge(array(95), $word, array(95));
23268: $tmpnumchars = $numchars + 2;
23269: $maxpos = $tmpnumchars - $charmin;
23270: for ($pos = 0; $pos < $maxpos; ++$pos) {
23271: $imax = min(($tmpnumchars - $pos), $charmax);
23272: for ($i = $charmin; $i <= $imax; ++$i) {
23273: $subword = strtolower($this->UTF8ArrSubString($tmpword, $pos, $pos + $i));
23274: if (isset($patterns[$subword])) {
23275: $pattern = $this->UTF8StringToArray($patterns[$subword]);
23276: $pattern_length = count($pattern);
23277: $digits = 1;
23278: for ($j = 0; $j < $pattern_length; ++$j) {
23279:
23280: if (($pattern[$j] >= 48) AND ($pattern[$j] <= 57)) {
23281: if ($j == 0) {
23282: $zero = $pos - 1;
23283: } else {
23284: $zero = $pos + $j - $digits;
23285: }
23286: if (!isset($hyphenword[$zero]) OR ($hyphenword[$zero] != $pattern[$j])) {
23287: $hyphenword[$zero] = $this->unichr($pattern[$j]);
23288: }
23289: ++$digits;
23290: }
23291: }
23292: }
23293: }
23294: }
23295: $inserted = 0;
23296: $maxpos = $numchars - $rightmin;
23297: for($i = $leftmin; $i <= $maxpos; ++$i) {
23298: if(isset($hyphenword[$i]) AND (($hyphenword[$i] % 2) != 0)) {
23299:
23300: array_splice($word, $i + $inserted, 0, 173);
23301: ++$inserted;
23302: }
23303: }
23304: return $word;
23305: }
23306:
23307: 23308: 23309: 23310: 23311: 23312: 23313: 23314:
23315: public function getHyphenPatternsFromTEX($file) {
23316:
23317:
23318: $data = file_get_contents($file);
23319: $patterns = array();
23320:
23321: $data = preg_replace('/\%[^\n]*/', '', $data);
23322:
23323: preg_match('/\\\\patterns\{([^\}]*)\}/i', $data, $matches);
23324: $data = trim(substr($matches[0], 10, -1));
23325:
23326: $patterns_array = preg_split('/[\s]+/', $data);
23327:
23328: $patterns = array();
23329: foreach($patterns_array as $val) {
23330: if (!$this->empty_string($val)) {
23331: $val = trim($val);
23332: $val = str_replace('\'', '\\\'', $val);
23333: $key = preg_replace('/[0-9]+/', '', $val);
23334: $patterns[$key] = $val;
23335: }
23336: }
23337: return $patterns;
23338: }
23339:
23340: 23341: 23342: 23343: 23344: 23345: 23346: 23347: 23348: 23349: 23350: 23351: 23352: 23353:
23354: public function hyphenateText($text, $patterns, $dictionary=array(), $leftmin=1, $rightmin=2, $charmin=1, $charmax=8) {
23355: $text = $this->unhtmlentities($text);
23356: $word = array();
23357: $txtarr = array();
23358: $intag = false;
23359: if (!is_array($patterns)) {
23360: $patterns = $this->getHyphenPatternsFromTEX($patterns);
23361: }
23362:
23363: $unichars = $this->UTF8StringToArray($text);
23364:
23365: foreach ($unichars as $char) {
23366: if ((!$intag) AND $this->unicode->uni_type[$char] == 'L') {
23367:
23368: $word[] = $char;
23369: } else {
23370:
23371: if (!$this->empty_string($word)) {
23372:
23373: $txtarr = array_merge($txtarr, $this->hyphenateWord($word, $patterns, $dictionary, $leftmin, $rightmin, $charmin, $charmax));
23374: $word = array();
23375: }
23376: $txtarr[] = $char;
23377: if (chr($char) == '<') {
23378:
23379: $intag = true;
23380: } elseif ($intag AND (chr($char) == '>')) {
23381:
23382: $intag = false;
23383: }
23384: }
23385: }
23386: if (!$this->empty_string($word)) {
23387:
23388: $txtarr = array_merge($txtarr, $this->hyphenateWord($word, $patterns, $dictionary, $leftmin, $rightmin, $charmin, $charmax));
23389: }
23390:
23391: return $this->UTF8ArrSubString($txtarr);
23392: }
23393:
23394: 23395: 23396: 23397: 23398: 23399:
23400: public function setRasterizeVectorImages($mode) {
23401: $this->rasterize_vector_images = $mode;
23402: }
23403:
23404: 23405: 23406: 23407: 23408: 23409: 23410: 23411: 23412: 23413: 23414: 23415: 23416: 23417: 23418: 23419: 23420: 23421: 23422: 23423: 23424: 23425:
23426: protected function getPathPaintOperator($style, $default='S') {
23427: $op = '';
23428: switch($style) {
23429: case 'S':
23430: case 'D': {
23431: $op = 'S';
23432: break;
23433: }
23434: case 's':
23435: case 'd': {
23436: $op = 's';
23437: break;
23438: }
23439: case 'f':
23440: case 'F': {
23441: $op = 'f';
23442: break;
23443: }
23444: case 'f*':
23445: case 'F*': {
23446: $op = 'f*';
23447: break;
23448: }
23449: case 'B':
23450: case 'FD':
23451: case 'DF': {
23452: $op = 'B';
23453: break;
23454: }
23455: case 'B*':
23456: case 'F*D':
23457: case 'DF*': {
23458: $op = 'B*';
23459: break;
23460: }
23461: case 'b':
23462: case 'fd':
23463: case 'df': {
23464: $op = 'b';
23465: break;
23466: }
23467: case 'b*':
23468: case 'f*d':
23469: case 'df*': {
23470: $op = 'b*';
23471: break;
23472: }
23473: case 'CNZ': {
23474: $op = 'W n';
23475: break;
23476: }
23477: case 'CEO': {
23478: $op = 'W* n';
23479: break;
23480: }
23481: case 'n': {
23482: $op = 'n';
23483: break;
23484: }
23485: default: {
23486: if (!empty($default)) {
23487: $op = $this->getPathPaintOperator($default, '');
23488: } else {
23489: $op = '';
23490: }
23491: }
23492: }
23493: return $op;
23494: }
23495:
23496: 23497: 23498: 23499: 23500: 23501: 23502:
23503: public function setFontSubsetting($enable=true) {
23504: $this->font_subsetting = $enable ? true : false;
23505: }
23506:
23507: 23508: 23509: 23510: 23511: 23512: 23513:
23514: public function getFontSubsetting() {
23515: return $this->font_subsetting;
23516: }
23517:
23518: 23519: 23520: 23521: 23522: 23523: 23524: 23525: 23526:
23527: public function stringLeftTrim($str, $replace='') {
23528: return preg_replace('/^'.$this->re_space['p'].'+/'.$this->re_space['m'], $replace, $str);
23529: }
23530:
23531: 23532: 23533: 23534: 23535: 23536: 23537: 23538: 23539:
23540: public function stringRightTrim($str, $replace='') {
23541: return preg_replace('/'.$this->re_space['p'].'+$/'.$this->re_space['m'], $replace, $str);
23542: }
23543:
23544: 23545: 23546: 23547: 23548: 23549: 23550: 23551: 23552:
23553: public function stringTrim($str, $replace='') {
23554: $str = $this->stringLeftTrim($str, $replace);
23555: $str = $this->stringRightTrim($str, $replace);
23556: return $str;
23557: }
23558:
23559: 23560: 23561: 23562: 23563: 23564: 23565:
23566: public function isUnicodeFont() {
23567: return (($this->CurrentFont['type'] == 'TrueTypeUnicode') OR ($this->CurrentFont['type'] == 'cidfont0'));
23568: }
23569:
23570: 23571: 23572: 23573: 23574: 23575: 23576: 23577:
23578: public function getFontFamilyName($fontfamily) {
23579:
23580: $fontfamily = preg_replace('/[^a-z0-9\,]/', '', strtolower($fontfamily));
23581:
23582: $fontslist = preg_split('/[,]/', $fontfamily);
23583:
23584: foreach ($fontslist as $font) {
23585:
23586: $font = preg_replace('/italic$/', 'I', $font);
23587: $font = preg_replace('/oblique$/', 'I', $font);
23588: $font = preg_replace('/bold([I]?)$/', 'B\\1', $font);
23589:
23590: $pattern = array();
23591: $replacement = array();
23592: $pattern[] = '/^serif|^cursive|^fantasy|^timesnewroman/';
23593: $replacement[] = 'times';
23594: $pattern[] = '/^sansserif/';
23595: $replacement[] = 'helvetica';
23596: $pattern[] = '/^monospace/';
23597: $replacement[] = 'courier';
23598: $font = preg_replace($pattern, $replacement, $font);
23599: if (in_array(strtolower($font), $this->fontlist) OR in_array($font, $this->fontkeys)) {
23600: return $font;
23601: }
23602: }
23603:
23604: return $this->CurrentFont['fontkey'];
23605: }
23606:
23607: 23608: 23609: 23610: 23611: 23612: 23613: 23614: 23615: 23616: 23617: 23618: 23619:
23620: public function startTemplate($w=0, $h=0) {
23621: if ($this->inxobj) {
23622:
23623: return false;
23624: }
23625: $this->inxobj = true;
23626: ++$this->n;
23627:
23628: $this->xobjid = 'XT'.$this->n;
23629:
23630: $this->xobjects[$this->xobjid] = array('n' => $this->n);
23631:
23632: $this->xobjects[$this->xobjid]['gvars'] = $this->getGraphicVars();
23633:
23634: $this->xobjects[$this->xobjid]['intmrk'] = 0;
23635: $this->xobjects[$this->xobjid]['transfmrk'] = array();
23636: $this->xobjects[$this->xobjid]['outdata'] = '';
23637: $this->xobjects[$this->xobjid]['xobjects'] = array();
23638: $this->xobjects[$this->xobjid]['images'] = array();
23639: $this->xobjects[$this->xobjid]['fonts'] = array();
23640: $this->xobjects[$this->xobjid]['annotations'] = array();
23641:
23642: $this->num_columns = 1;
23643: $this->current_column = 0;
23644: $this->SetAutoPageBreak(false);
23645: if (($w === '') OR ($w <= 0)) {
23646: $w = $this->w - $this->lMargin - $this->rMargin;
23647: }
23648: if (($h === '') OR ($h <= 0)) {
23649: $h = $this->h - $this->tMargin - $this->bMargin;
23650: }
23651: $this->xobjects[$this->xobjid]['x'] = 0;
23652: $this->xobjects[$this->xobjid]['y'] = 0;
23653: $this->xobjects[$this->xobjid]['w'] = $w;
23654: $this->xobjects[$this->xobjid]['h'] = $h;
23655: $this->w = $w;
23656: $this->h = $h;
23657: $this->wPt = $this->w * $this->k;
23658: $this->hPt = $this->h * $this->k;
23659: $this->fwPt = $this->wPt;
23660: $this->fhPt = $this->hPt;
23661: $this->x = 0;
23662: $this->y = 0;
23663: $this->lMargin = 0;
23664: $this->rMargin = 0;
23665: $this->tMargin = 0;
23666: $this->bMargin = 0;
23667: return $this->xobjid;
23668: }
23669:
23670: 23671: 23672: 23673: 23674: 23675: 23676: 23677: 23678: 23679:
23680: public function endTemplate() {
23681: if (!$this->inxobj) {
23682:
23683: return false;
23684: }
23685: $this->inxobj = false;
23686:
23687: $this->setGraphicVars($this->xobjects[$this->xobjid]['gvars'], true);
23688: return $this->xobjid;
23689: }
23690:
23691: 23692: 23693: 23694: 23695: 23696: 23697: 23698: 23699: 23700: 23701: 23702: 23703: 23704: 23705: 23706: 23707: 23708:
23709: public function printTemplate($id, $x='', $y='', $w=0, $h=0, $align='', $palign='', $fitonpage=false) {
23710: if (!isset($this->xobjects[$id])) {
23711: $this->Error('The XObject Template \''.$id.'\' doesn\'t exist!');
23712: }
23713: if ($this->inxobj) {
23714: if ($id == $this->xobjid) {
23715:
23716: $this->endTemplate();
23717: } else {
23718:
23719: $this->xobjects[$this->xobjid]['xobjects'][$id] = $this->xobjects[$id];
23720: }
23721: }
23722:
23723: if ($x === '') {
23724: $x = $this->x;
23725: }
23726: if ($y === '') {
23727: $y = $this->y;
23728: }
23729:
23730: $this->checkPageRegions($h, $x, $y);
23731: $ow = $this->xobjects[$id]['w'];
23732: $oh = $this->xobjects[$id]['h'];
23733:
23734: if (($w <= 0) AND ($h <= 0)) {
23735: $w = $ow;
23736: $h = $oh;
23737: } elseif ($w <= 0) {
23738: $w = $h * $ow / $oh;
23739: } elseif ($h <= 0) {
23740: $h = $w * $oh / $ow;
23741: }
23742:
23743: $this->fitBlock($w, $h, $x, $y, $fitonpage);
23744:
23745: $rb_y = $y + $h;
23746:
23747: if ($this->rtl) {
23748: if ($palign == 'L') {
23749: $xt = $this->lMargin;
23750: } elseif ($palign == 'C') {
23751: $xt = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
23752: } elseif ($palign == 'R') {
23753: $xt = $this->w - $this->rMargin - $w;
23754: } else {
23755: $xt = $x - $w;
23756: }
23757: $rb_x = $xt;
23758: } else {
23759: if ($palign == 'L') {
23760: $xt = $this->lMargin;
23761: } elseif ($palign == 'C') {
23762: $xt = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
23763: } elseif ($palign == 'R') {
23764: $xt = $this->w - $this->rMargin - $w;
23765: } else {
23766: $xt = $x;
23767: }
23768: $rb_x = $xt + $w;
23769: }
23770:
23771: $this->StartTransform();
23772:
23773: $sx = ($w / $this->xobjects[$id]['w']);
23774: $sy = ($h / $this->xobjects[$id]['h']);
23775: $tm = array();
23776: $tm[0] = $sx;
23777: $tm[1] = 0;
23778: $tm[2] = 0;
23779: $tm[3] = $sy;
23780: $tm[4] = $xt * $this->k;
23781: $tm[5] = ($this->h - $h - $y) * $this->k;
23782: $this->Transform($tm);
23783:
23784: $this->_out('/'.$id.' Do');
23785: $this->StopTransform();
23786:
23787: if (!empty($this->xobjects[$id]['annotations'])) {
23788: foreach ($this->xobjects[$id]['annotations'] as $annot) {
23789:
23790: $coordlt = $this->getTransformationMatrixProduct($tm, array(1, 0, 0, 1, ($annot['x'] * $this->k), (-$annot['y'] * $this->k)));
23791: $ax = ($coordlt[4] / $this->k);
23792: $ay = ($this->h - $h - ($coordlt[5] / $this->k));
23793: $coordrb = $this->getTransformationMatrixProduct($tm, array(1, 0, 0, 1, (($annot['x'] + $annot['w']) * $this->k), ((-$annot['y'] - $annot['h']) * $this->k)));
23794: $aw = ($coordrb[4] / $this->k) - $ax;
23795: $ah = ($this->h - $h - ($coordrb[5] / $this->k)) - $ay;
23796: $this->Annotation($ax, $ay, $aw, $ah, $annot['text'], $annot['opt'], $annot['spaces']);
23797: }
23798: }
23799:
23800: switch($align) {
23801: case 'T': {
23802: $this->y = $y;
23803: $this->x = $rb_x;
23804: break;
23805: }
23806: case 'M': {
23807: $this->y = $y + round($h/2);
23808: $this->x = $rb_x;
23809: break;
23810: }
23811: case 'B': {
23812: $this->y = $rb_y;
23813: $this->x = $rb_x;
23814: break;
23815: }
23816: case 'N': {
23817: $this->SetY($rb_y);
23818: break;
23819: }
23820: default:{
23821: break;
23822: }
23823: }
23824: }
23825:
23826: 23827: 23828: 23829: 23830: 23831: 23832:
23833: public function setFontStretching($perc=100) {
23834: $this->font_stretching = $perc;
23835: }
23836:
23837: 23838: 23839: 23840: 23841: 23842: 23843:
23844: public function getFontStretching() {
23845: return $this->font_stretching;
23846: }
23847:
23848: 23849: 23850: 23851: 23852: 23853: 23854:
23855: public function setFontSpacing($spacing=0) {
23856: $this->font_spacing = $spacing;
23857: }
23858:
23859: 23860: 23861: 23862: 23863: 23864: 23865:
23866: public function getFontSpacing() {
23867: return $this->font_spacing;
23868: }
23869:
23870: 23871: 23872: 23873: 23874: 23875: 23876: 23877:
23878: public function () {
23879: return $this->page_regions;
23880: }
23881:
23882: 23883: 23884: 23885: 23886: 23887: 23888: 23889: 23890: 23891: 23892:
23893: public function ($regions=array()) {
23894:
23895: $this->page_regions = array();
23896:
23897: foreach ($regions as $data) {
23898: $this->addPageRegion($data);
23899: }
23900: }
23901:
23902: 23903: 23904: 23905: 23906: 23907: 23908: 23909: 23910: 23911: 23912:
23913: public function ($region) {
23914: if (!isset($region['page']) OR empty($region['page'])) {
23915: $region['page'] = $this->page;
23916: }
23917: if (isset($region['xt']) AND isset($region['xb']) AND ($region['xt'] > 0) AND ($region['xb'] > 0)
23918: AND isset($region['yt']) AND isset($region['yb']) AND ($region['yt'] >= 0) AND ($region['yt'] < $region['yb'])
23919: AND isset($region['side']) AND (($region['side'] == 'L') OR ($region['side'] == 'R'))) {
23920: $this->page_regions[] = $region;
23921: }
23922: }
23923:
23924: 23925: 23926: 23927: 23928: 23929: 23930: 23931:
23932: public function ($key) {
23933: if (isset($this->page_regions[$key])) {
23934: unset($this->page_regions[$key]);
23935: }
23936: }
23937:
23938: 23939: 23940: 23941: 23942: 23943: 23944: 23945: 23946: 23947: 23948:
23949: protected function ($h=0, &$x='', &$y='') {
23950:
23951: if ($x === '') {
23952: $x = &$this->x;
23953: }
23954: if ($y === '') {
23955: $y = &$this->y;
23956: }
23957: if (empty($this->page_regions)) {
23958:
23959: return;
23960: }
23961: if (empty($h)) {
23962: $h = ($this->FontSize * $this->cell_height_ratio) + $this->cell_padding['T'] + $this->cell_padding['B'];
23963: }
23964: if ($this->rtl) {
23965: $this->lMargin = $this->original_lMargin;
23966: } else {
23967: $this->rMargin = $this->original_rMargin;
23968: }
23969: if ($this->AutoPageBreak AND !$this->InFooter AND (($y + $h) > $this->PageBreakTrigger)) {
23970:
23971: return;
23972: }
23973:
23974: foreach ($this->page_regions as $regid => $regdata) {
23975: if ($regdata['page'] == $this->page) {
23976:
23977: if (($y > ($regdata['yt'] - $h)) AND ($y <= $regdata['yb'])) {
23978:
23979: $minv = ($regdata['xb'] - $regdata['xt']) / ($regdata['yb'] - $regdata['yt']);
23980: $yt = max($y, $regdata['yt']);
23981: $yb = min(($yt + $h), $regdata['yb']);
23982: $xt = (($yt - $regdata['yt']) * $minv) + $regdata['xt'];
23983: $xb = (($yb - $regdata['yt']) * $minv) + $regdata['xt'];
23984: if ($regdata['side'] == 'L') {
23985: $new_margin = max($xt, $xb);
23986: if ($this->lMargin < $new_margin) {
23987: if ($this->rtl) {
23988:
23989: $this->lMargin = $new_margin;
23990: }
23991: if ($x < $new_margin) {
23992:
23993: $x = $new_margin;
23994: }
23995: }
23996: } elseif ($regdata['side'] == 'R') {
23997: $new_margin = min($xt, $xb);
23998: if (($this->w - $this->rMargin) > $new_margin) {
23999: if (!$this->rtl) {
24000:
24001: $this->rMargin = ($this->w - $new_margin);
24002: }
24003: if ($x > $new_margin) {
24004:
24005: $x = $new_margin;
24006: }
24007: }
24008: }
24009: }
24010: }
24011: }
24012: }
24013:
24014:
24015:
24016:
24017:
24018: 24019: 24020: 24021: 24022: 24023: 24024: 24025: 24026: 24027: 24028: 24029: 24030: 24031: 24032: 24033: 24034:
24035: public function ImageSVG($file, $x='', $y='', $w=0, $h=0, $link='', $align='', $palign='', $border=0, $fitonpage=false) {
24036: if ($this->rasterize_vector_images AND ($w > 0) AND ($h > 0)) {
24037:
24038: return $this->Image($file, $x, $y, $w, $h, 'SVG', $link, $align, true, 300, $palign, false, false, $border, false, false, false);
24039: }
24040: $this->svgdir = dirname($file);
24041: $svgdata = file_get_contents($file);
24042: if ($svgdata === false) {
24043: $this->Error('SVG file not found: '.$file);
24044: }
24045: if ($x === '') {
24046: $x = $this->x;
24047: }
24048: if ($y === '') {
24049: $y = $this->y;
24050: }
24051:
24052: $this->checkPageRegions($x, $y);
24053: $k = $this->k;
24054: $ox = 0;
24055: $oy = 0;
24056: $ow = $w;
24057: $oh = $h;
24058: $aspect_ratio_align = 'xMidYMid';
24059: $aspect_ratio_ms = 'meet';
24060: $regs = array();
24061:
24062: preg_match('/<svg([^\>]*)>/si', $svgdata, $regs);
24063: if (isset($regs[1]) AND !empty($regs[1])) {
24064: $tmp = array();
24065: if (preg_match('/[\s]+x[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) {
24066: $ox = $this->getHTMLUnitToUnits($tmp[1], 0, $this->svgunit, false);
24067: }
24068: $tmp = array();
24069: if (preg_match('/[\s]+y[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) {
24070: $oy = $this->getHTMLUnitToUnits($tmp[1], 0, $this->svgunit, false);
24071: }
24072: $tmp = array();
24073: if (preg_match('/[\s]+width[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) {
24074: $ow = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false);
24075: }
24076: $tmp = array();
24077: if (preg_match('/[\s]+height[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) {
24078: $oh = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false);
24079: }
24080: $tmp = array();
24081: $view_box = array();
24082: if (preg_match('/[\s]+viewBox[\s]*=[\s]*"[\s]*([0-9\.\-]+)[\s]+([0-9\.\-]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]*"/si', $regs[1], $tmp)) {
24083: if (count($tmp) == 5) {
24084: array_shift($tmp);
24085: foreach ($tmp as $key => $val) {
24086: $view_box[$key] = $this->getHTMLUnitToUnits($val, 0, $this->svgunit, false);
24087: }
24088: $ox = $view_box[0];
24089: $oy = $view_box[1];
24090: }
24091:
24092: $tmp = array();
24093: if (preg_match('/[\s]+preserveAspectRatio[\s]*=[\s]*"([^"]*)"/si', $regs[1], $tmp)) {
24094: $aspect_ratio = preg_split('/[\s]+/si', $tmp[1]);
24095: switch (count($aspect_ratio)) {
24096: case 3: {
24097: $aspect_ratio_align = $aspect_ratio[1];
24098: $aspect_ratio_ms = $aspect_ratio[2];
24099: break;
24100: }
24101: case 2: {
24102: $aspect_ratio_align = $aspect_ratio[0];
24103: $aspect_ratio_ms = $aspect_ratio[1];
24104: break;
24105: }
24106: case 1: {
24107: $aspect_ratio_align = $aspect_ratio[0];
24108: $aspect_ratio_ms = 'meet';
24109: break;
24110: }
24111: }
24112: }
24113: }
24114: }
24115:
24116: if (($w <= 0) AND ($h <= 0)) {
24117:
24118: $w = $ow;
24119: $h = $oh;
24120: } elseif ($w <= 0) {
24121: $w = $h * $ow / $oh;
24122: } elseif ($h <= 0) {
24123: $h = $w * $oh / $ow;
24124: }
24125:
24126: $this->fitBlock($w, $h, $x, $y, $fitonpage);
24127: if ($this->rasterize_vector_images) {
24128:
24129: return $this->Image($file, $x, $y, $w, $h, 'SVG', $link, $align, true, 300, $palign, false, false, $border, false, false, false);
24130: }
24131:
24132: $this->img_rb_y = $y + $h;
24133:
24134: if ($this->rtl) {
24135: if ($palign == 'L') {
24136: $ximg = $this->lMargin;
24137: } elseif ($palign == 'C') {
24138: $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
24139: } elseif ($palign == 'R') {
24140: $ximg = $this->w - $this->rMargin - $w;
24141: } else {
24142: $ximg = $x - $w;
24143: }
24144: $this->img_rb_x = $ximg;
24145: } else {
24146: if ($palign == 'L') {
24147: $ximg = $this->lMargin;
24148: } elseif ($palign == 'C') {
24149: $ximg = ($this->w + $this->lMargin - $this->rMargin - $w) / 2;
24150: } elseif ($palign == 'R') {
24151: $ximg = $this->w - $this->rMargin - $w;
24152: } else {
24153: $ximg = $x;
24154: }
24155: $this->img_rb_x = $ximg + $w;
24156: }
24157:
24158: $gvars = $this->getGraphicVars();
24159:
24160: $svgoffset_x = ($ximg - $ox) * $this->k;
24161: $svgoffset_y = -($y - $oy) * $this->k;
24162: if (isset($view_box[2]) AND ($view_box[2] > 0) AND ($view_box[3] > 0)) {
24163: $ow = $view_box[2];
24164: $oh = $view_box[3];
24165: }
24166: $svgscale_x = $w / $ow;
24167: $svgscale_y = $h / $oh;
24168:
24169: if ($aspect_ratio_align != 'none') {
24170:
24171: $svgscale_old_x = $svgscale_x;
24172: $svgscale_old_y = $svgscale_y;
24173:
24174: if ($aspect_ratio_ms == 'slice') {
24175:
24176: if ($svgscale_x > $svgscale_y) {
24177: $svgscale_y = $svgscale_x;
24178: } elseif ($svgscale_x < $svgscale_y) {
24179: $svgscale_x = $svgscale_y;
24180: }
24181: } else {
24182:
24183: if ($svgscale_x < $svgscale_y) {
24184: $svgscale_y = $svgscale_x;
24185: } elseif ($svgscale_x > $svgscale_y) {
24186: $svgscale_x = $svgscale_y;
24187: }
24188: }
24189:
24190: switch (substr($aspect_ratio_align, 1, 3)) {
24191: case 'Min': {
24192:
24193: break;
24194: }
24195: case 'Max': {
24196: $svgoffset_x += (($w * $this->k) - ($ow * $this->k * $svgscale_x));
24197: break;
24198: }
24199: default:
24200: case 'Mid': {
24201: $svgoffset_x += ((($w * $this->k) - ($ow * $this->k * $svgscale_x)) / 2);
24202: break;
24203: }
24204: }
24205:
24206: switch (substr($aspect_ratio_align, 5)) {
24207: case 'Min': {
24208:
24209: break;
24210: }
24211: case 'Max': {
24212: $svgoffset_y -= (($h * $this->k) - ($oh * $this->k * $svgscale_y));
24213: break;
24214: }
24215: default:
24216: case 'Mid': {
24217: $svgoffset_y -= ((($h * $this->k) - ($oh * $this->k * $svgscale_y)) / 2);
24218: break;
24219: }
24220: }
24221: }
24222:
24223: $page_break_mode = $this->AutoPageBreak;
24224: $page_break_margin = $this->getBreakMargin();
24225: $cell_padding = $this->cell_padding;
24226: $this->SetCellPadding(0);
24227: $this->SetAutoPageBreak(false);
24228:
24229: $this->_out('q'.$this->epsmarker);
24230:
24231: $this->Rect($x, $y, $w, $h, 'CNZ', array(), array());
24232:
24233: $e = $ox * $this->k * (1 - $svgscale_x);
24234: $f = ($this->h - $oy) * $this->k * (1 - $svgscale_y);
24235: $this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', $svgscale_x, 0, 0, $svgscale_y, $e + $svgoffset_x, $f + $svgoffset_y));
24236:
24237: $this->parser = xml_parser_create('UTF-8');
24238:
24239: xml_set_object($this->parser, $this);
24240:
24241: xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
24242:
24243: xml_set_element_handler($this->parser, 'startSVGElementHandler', 'endSVGElementHandler');
24244:
24245: xml_set_character_data_handler($this->parser, 'segSVGContentHandler');
24246:
24247: if(!xml_parse($this->parser, $svgdata)) {
24248: $error_message = sprintf("SVG Error: %s at line %d", xml_error_string(xml_get_error_code($this->parser)), xml_get_current_line_number($this->parser));
24249: $this->Error($error_message);
24250: }
24251:
24252: xml_parser_free($this->parser);
24253:
24254: $this->_out($this->epsmarker.'Q');
24255:
24256: $this->setGraphicVars($gvars);
24257: $this->lasth = $gvars['lasth'];
24258: if (!empty($border)) {
24259: $bx = $this->x;
24260: $by = $this->y;
24261: $this->x = $ximg;
24262: if ($this->rtl) {
24263: $this->x += $w;
24264: }
24265: $this->y = $y;
24266: $this->Cell($w, $h, '', $border, 0, '', 0, '', 0, true);
24267: $this->x = $bx;
24268: $this->y = $by;
24269: }
24270: if ($link) {
24271: $this->Link($ximg, $y, $w, $h, $link, 0);
24272: }
24273:
24274: switch($align) {
24275: case 'T':{
24276: $this->y = $y;
24277: $this->x = $this->img_rb_x;
24278: break;
24279: }
24280: case 'M':{
24281: $this->y = $y + round($h/2);
24282: $this->x = $this->img_rb_x;
24283: break;
24284: }
24285: case 'B':{
24286: $this->y = $this->img_rb_y;
24287: $this->x = $this->img_rb_x;
24288: break;
24289: }
24290: case 'N':{
24291: $this->SetY($this->img_rb_y);
24292: break;
24293: }
24294: default:{
24295:
24296: $this->x = $gvars['x'];
24297: $this->y = $gvars['y'];
24298: $this->page = $gvars['page'];
24299: $this->current_column = $gvars['current_column'];
24300: $this->tMargin = $gvars['tMargin'];
24301: $this->bMargin = $gvars['bMargin'];
24302: $this->w = $gvars['w'];
24303: $this->h = $gvars['h'];
24304: $this->wPt = $gvars['wPt'];
24305: $this->hPt = $gvars['hPt'];
24306: $this->fwPt = $gvars['fwPt'];
24307: $this->fhPt = $gvars['fhPt'];
24308: break;
24309: }
24310: }
24311: $this->endlinex = $this->img_rb_x;
24312:
24313: $this->SetAutoPageBreak($page_break_mode, $page_break_margin);
24314: $this->cell_padding = $cell_padding;
24315: }
24316:
24317: 24318: 24319: 24320: 24321: 24322: 24323: 24324:
24325: protected function getSVGTransformMatrix($attribute) {
24326:
24327: $tm = array(1, 0, 0, 1, 0, 0);
24328: $transform = array();
24329: if (preg_match_all('/(matrix|translate|scale|rotate|skewX|skewY)[\s]*\(([^\)]+)\)/si', $attribute, $transform, PREG_SET_ORDER) > 0) {
24330: foreach ($transform as $key => $data) {
24331: if (!empty($data[2])) {
24332: $a = 1;
24333: $b = 0;
24334: $c = 0;
24335: $d = 1;
24336: $e = 0;
24337: $f = 0;
24338: $regs = array();
24339: switch ($data[1]) {
24340: case 'matrix': {
24341: if (preg_match('/([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) {
24342: $a = $regs[1];
24343: $b = $regs[2];
24344: $c = $regs[3];
24345: $d = $regs[4];
24346: $e = $regs[5];
24347: $f = $regs[6];
24348: }
24349: break;
24350: }
24351: case 'translate': {
24352: if (preg_match('/([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) {
24353: $e = $regs[1];
24354: $f = $regs[2];
24355: } elseif (preg_match('/([a-z0-9\-\.]+)/si', $data[2], $regs)) {
24356: $e = $regs[1];
24357: }
24358: break;
24359: }
24360: case 'scale': {
24361: if (preg_match('/([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) {
24362: $a = $regs[1];
24363: $d = $regs[2];
24364: } elseif (preg_match('/([a-z0-9\-\.]+)/si', $data[2], $regs)) {
24365: $a = $regs[1];
24366: $d = $a;
24367: }
24368: break;
24369: }
24370: case 'rotate': {
24371: if (preg_match('/([0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)[\,\s]+([a-z0-9\-\.]+)/si', $data[2], $regs)) {
24372: $ang = deg2rad($regs[1]);
24373: $x = $regs[2];
24374: $y = $regs[3];
24375: $a = cos($ang);
24376: $b = sin($ang);
24377: $c = -$b;
24378: $d = $a;
24379: $e = ($x * (1 - $a)) - ($y * $c);
24380: $f = ($y * (1 - $d)) - ($x * $b);
24381: } elseif (preg_match('/([0-9\-\.]+)/si', $data[2], $regs)) {
24382: $ang = deg2rad($regs[1]);
24383: $a = cos($ang);
24384: $b = sin($ang);
24385: $c = -$b;
24386: $d = $a;
24387: $e = 0;
24388: $f = 0;
24389: }
24390: break;
24391: }
24392: case 'skewX': {
24393: if (preg_match('/([0-9\-\.]+)/si', $data[2], $regs)) {
24394: $c = tan(deg2rad($regs[1]));
24395: }
24396: break;
24397: }
24398: case 'skewY': {
24399: if (preg_match('/([0-9\-\.]+)/si', $data[2], $regs)) {
24400: $b = tan(deg2rad($regs[1]));
24401: }
24402: break;
24403: }
24404: }
24405: $tm = $this->getTransformationMatrixProduct($tm, array($a, $b, $c, $d, $e, $f));
24406: }
24407: }
24408: }
24409: return $tm;
24410: }
24411:
24412: 24413: 24414: 24415: 24416: 24417: 24418: 24419: 24420:
24421: protected function getTransformationMatrixProduct($ta, $tb) {
24422: $tm = array();
24423: $tm[0] = ($ta[0] * $tb[0]) + ($ta[2] * $tb[1]);
24424: $tm[1] = ($ta[1] * $tb[0]) + ($ta[3] * $tb[1]);
24425: $tm[2] = ($ta[0] * $tb[2]) + ($ta[2] * $tb[3]);
24426: $tm[3] = ($ta[1] * $tb[2]) + ($ta[3] * $tb[3]);
24427: $tm[4] = ($ta[0] * $tb[4]) + ($ta[2] * $tb[5]) + $ta[4];
24428: $tm[5] = ($ta[1] * $tb[4]) + ($ta[3] * $tb[5]) + $ta[5];
24429: return $tm;
24430: }
24431:
24432: 24433: 24434: 24435: 24436: 24437: 24438:
24439: protected function convertSVGtMatrix($tm) {
24440: $a = $tm[0];
24441: $b = -$tm[1];
24442: $c = -$tm[2];
24443: $d = $tm[3];
24444: $e = $this->getHTMLUnitToUnits($tm[4], 1, $this->svgunit, false) * $this->k;
24445: $f = -$this->getHTMLUnitToUnits($tm[5], 1, $this->svgunit, false) * $this->k;
24446: $x = 0;
24447: $y = $this->h * $this->k;
24448: $e = ($x * (1 - $a)) - ($y * $c) + $e;
24449: $f = ($y * (1 - $d)) - ($x * $b) + $f;
24450: return array($a, $b, $c, $d, $e, $f);
24451: }
24452:
24453: 24454: 24455: 24456: 24457: 24458:
24459: protected function SVGTransform($tm) {
24460: $this->Transform($this->convertSVGtMatrix($tm));
24461: }
24462:
24463: 24464: 24465: 24466: 24467: 24468: 24469: 24470: 24471: 24472: 24473: 24474: 24475: 24476: 24477:
24478: protected function setSVGStyles($svgstyle, $prevsvgstyle, $x=0, $y=0, $w=1, $h=1, $clip_function='', $clip_params=array()) {
24479: $objstyle = '';
24480: if(!isset($svgstyle['opacity'])) {
24481: return $objstyle;
24482: }
24483:
24484: $regs = array();
24485: if (preg_match('/url\([\s]*\#([^\)]*)\)/si', $svgstyle['clip-path'], $regs)) {
24486: $clip_path = $this->svgclippaths[$regs[1]];
24487: foreach ($clip_path as $cp) {
24488: $this->startSVGElementHandler('clip-path', $cp['name'], $cp['attribs'], $cp['tm']);
24489: }
24490: }
24491:
24492: if ($svgstyle['opacity'] != 1) {
24493: $this->SetAlpha($svgstyle['opacity']);
24494: }
24495:
24496: $fill_color = $this->convertHTMLColorToDec($svgstyle['color']);
24497: $this->SetFillColorArray($fill_color);
24498:
24499: $text_color = $this->convertHTMLColorToDec($svgstyle['text-color']);
24500: $this->SetTextColorArray($text_color);
24501:
24502: if (preg_match('/rect\(([a-z0-9\-\.]*)[\s]*([a-z0-9\-\.]*)[\s]*([a-z0-9\-\.]*)[\s]*([a-z0-9\-\.]*)\)/si', $svgstyle['clip'], $regs)) {
24503: $top = (isset($regs[1])?$this->getHTMLUnitToUnits($regs[1], 0, $this->svgunit, false):0);
24504: $right = (isset($regs[2])?$this->getHTMLUnitToUnits($regs[2], 0, $this->svgunit, false):0);
24505: $bottom = (isset($regs[3])?$this->getHTMLUnitToUnits($regs[3], 0, $this->svgunit, false):0);
24506: $left = (isset($regs[4])?$this->getHTMLUnitToUnits($regs[4], 0, $this->svgunit, false):0);
24507: $cx = $x + $left;
24508: $cy = $y + $top;
24509: $cw = $w - $left - $right;
24510: $ch = $h - $top - $bottom;
24511: if ($svgstyle['clip-rule'] == 'evenodd') {
24512: $clip_rule = 'CNZ';
24513: } else {
24514: $clip_rule = 'CEO';
24515: }
24516: $this->Rect($cx, $cy, $cw, $ch, $clip_rule, array(), array());
24517: }
24518:
24519: $regs = array();
24520: if (preg_match('/url\([\s]*\#([^\)]*)\)/si', $svgstyle['fill'], $regs)) {
24521:
24522: $gradient = $this->svggradients[$regs[1]];
24523: if (isset($gradient['xref'])) {
24524:
24525: $newgradient = $this->svggradients[$gradient['xref']];
24526: $newgradient['coords'] = $gradient['coords'];
24527: $newgradient['mode'] = $gradient['mode'];
24528: $newgradient['gradientUnits'] = $gradient['gradientUnits'];
24529: if (isset($gradient['gradientTransform'])) {
24530: $newgradient['gradientTransform'] = $gradient['gradientTransform'];
24531: }
24532: $gradient = $newgradient;
24533: }
24534:
24535: $this->_out('q');
24536:
24537: if (!empty($clip_function) AND method_exists($this, $clip_function)) {
24538: $bbox = call_user_func_array(array($this, $clip_function), $clip_params);
24539: if (is_array($bbox) AND (count($bbox) == 4)) {
24540: list($x, $y, $w, $h) = $bbox;
24541: }
24542: }
24543: if ($gradient['mode'] == 'measure') {
24544: if (isset($gradient['gradientTransform']) AND !empty($gradient['gradientTransform'])) {
24545: $gtm = $gradient['gradientTransform'];
24546:
24547: $xa = ($gtm[0] * $gradient['coords'][0]) + ($gtm[2] * $gradient['coords'][1]) + $gtm[4];
24548: $ya = ($gtm[1] * $gradient['coords'][0]) + ($gtm[3] * $gradient['coords'][1]) + $gtm[5];
24549: $xb = ($gtm[0] * $gradient['coords'][2]) + ($gtm[2] * $gradient['coords'][3]) + $gtm[4];
24550: $yb = ($gtm[1] * $gradient['coords'][2]) + ($gtm[3] * $gradient['coords'][3]) + $gtm[5];
24551: if (isset($gradient['coords'][4])) {
24552: $gradient['coords'][4] = sqrt(pow(($gtm[0] * $gradient['coords'][4]), 2) + pow(($gtm[1] * $gradient['coords'][4]), 2));
24553: }
24554: $gradient['coords'][0] = $xa;
24555: $gradient['coords'][1] = $ya;
24556: $gradient['coords'][2] = $xb;
24557: $gradient['coords'][3] = $yb;
24558:
24559: }
24560:
24561: $gradient['coords'][0] = $this->getHTMLUnitToUnits($gradient['coords'][0], 0, $this->svgunit, false);
24562: $gradient['coords'][1] = $this->getHTMLUnitToUnits($gradient['coords'][1], 0, $this->svgunit, false);
24563: $gradient['coords'][2] = $this->getHTMLUnitToUnits($gradient['coords'][2], 0, $this->svgunit, false);
24564: $gradient['coords'][3] = $this->getHTMLUnitToUnits($gradient['coords'][3], 0, $this->svgunit, false);
24565: if (isset($gradient['coords'][4])) {
24566: $gradient['coords'][4] = $this->getHTMLUnitToUnits($gradient['coords'][4], 0, $this->svgunit, false);
24567: }
24568:
24569: if ($gradient['gradientUnits'] == 'objectBoundingBox') {
24570:
24571: $gradient['coords'][0] += $x;
24572: $gradient['coords'][1] += $y;
24573: $gradient['coords'][2] += $x;
24574: $gradient['coords'][3] += $y;
24575: }
24576:
24577: $gradient['coords'][0] = ($gradient['coords'][0] - $x) / $w;
24578: $gradient['coords'][1] = ($gradient['coords'][1] - $y) / $h;
24579: $gradient['coords'][2] = ($gradient['coords'][2] - $x) / $w;
24580: $gradient['coords'][3] = ($gradient['coords'][3] - $y) / $h;
24581: if (isset($gradient['coords'][4])) {
24582: $gradient['coords'][4] /= $w;
24583: }
24584:
24585: foreach($gradient['coords'] as $key => $val) {
24586: if ($val < 0) {
24587: $gradient['coords'][$key] = 0;
24588: } elseif ($val > 1) {
24589: $gradient['coords'][$key] = 1;
24590: }
24591: }
24592: if (($gradient['type'] == 2) AND ($gradient['coords'][0] == $gradient['coords'][2]) AND ($gradient['coords'][1] == $gradient['coords'][3])) {
24593:
24594: $gradient['coords'][0] = 1;
24595: $gradient['coords'][1] = 0;
24596: $gradient['coords'][2] = 0.999;
24597: $gradient['coords'][3] = 0;
24598: }
24599: }
24600:
24601: $tmp = $gradient['coords'][1];
24602: $gradient['coords'][1] = $gradient['coords'][3];
24603: $gradient['coords'][3] = $tmp;
24604:
24605: if (($gradient['type'] == 3) AND ($gradient['mode'] == 'measure')) {
24606:
24607: $cy = $this->h - $y - ($gradient['coords'][1] * ($w + $h));
24608: $this->_out(sprintf('%.3F 0 0 %.3F %.3F %.3F cm', $w*$this->k, $w*$this->k, $x*$this->k, $cy*$this->k));
24609: } else {
24610: $this->_out(sprintf('%.3F 0 0 %.3F %.3F %.3F cm', $w*$this->k, $h*$this->k, $x*$this->k, ($this->h-($y+$h))*$this->k));
24611: }
24612: if (count($gradient['stops']) > 1) {
24613: $this->Gradient($gradient['type'], $gradient['coords'], $gradient['stops'], array(), false);
24614: }
24615: } elseif ($svgstyle['fill'] != 'none') {
24616: $fill_color = $this->convertHTMLColorToDec($svgstyle['fill']);
24617: if ($svgstyle['fill-opacity'] != 1) {
24618: $this->SetAlpha($svgstyle['fill-opacity']);
24619: }
24620: $this->SetFillColorArray($fill_color);
24621: if ($svgstyle['fill-rule'] == 'evenodd') {
24622: $objstyle .= 'F*';
24623: } else {
24624: $objstyle .= 'F';
24625: }
24626: }
24627:
24628: if ($svgstyle['stroke'] != 'none') {
24629: $stroke_style = array(
24630: 'color' => $this->convertHTMLColorToDec($svgstyle['stroke']),
24631: 'width' => $this->getHTMLUnitToUnits($svgstyle['stroke-width'], 0, $this->svgunit, false),
24632: 'cap' => $svgstyle['stroke-linecap'],
24633: 'join' => $svgstyle['stroke-linejoin']
24634: );
24635: if (isset($svgstyle['stroke-dasharray']) AND !empty($svgstyle['stroke-dasharray']) AND ($svgstyle['stroke-dasharray'] != 'none')) {
24636: $stroke_style['dash'] = $svgstyle['stroke-dasharray'];
24637: }
24638: $this->SetLineStyle($stroke_style);
24639: $objstyle .= 'D';
24640: }
24641:
24642: $regs = array();
24643: if (!empty($svgstyle['font'])) {
24644: if (preg_match('/font-family[\s]*:[\s]*([^\;\"]*)/si', $svgstyle['font'], $regs)) {
24645: $font_family = $this->getFontFamilyName($regs[1]);
24646: } else {
24647: $font_family = $svgstyle['font-family'];
24648: }
24649: if (preg_match('/font-size[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) {
24650: $font_size = trim($regs[1]);
24651: } else {
24652: $font_size = $svgstyle['font-size'];
24653: }
24654: if (preg_match('/font-style[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) {
24655: $font_style = trim($regs[1]);
24656: } else {
24657: $font_style = $svgstyle['font-style'];
24658: }
24659: if (preg_match('/font-weight[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) {
24660: $font_weight = trim($regs[1]);
24661: } else {
24662: $font_weight = $svgstyle['font-weight'];
24663: }
24664: if (preg_match('/font-stretch[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) {
24665: $font_stretch = trim($regs[1]);
24666: } else {
24667: $font_stretch = $svgstyle['font-stretch'];
24668: }
24669: if (preg_match('/letter-spacing[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) {
24670: $font_spacing = trim($regs[1]);
24671: } else {
24672: $font_spacing = $svgstyle['letter-spacing'];
24673: }
24674: } else {
24675: $font_family = $this->getFontFamilyName($svgstyle['font-family']);
24676: $font_size = $svgstyle['font-size'];
24677: $font_style = $svgstyle['font-style'];
24678: $font_weight = $svgstyle['font-weight'];
24679: $font_stretch = $svgstyle['font-stretch'];
24680: $font_spacing = $svgstyle['letter-spacing'];
24681: }
24682: $font_size = $this->getHTMLUnitToUnits($font_size, $prevsvgstyle['font-size'], $this->svgunit, false) * $this->k;
24683: $font_stretch = $this->getCSSFontStretching($font_stretch, $svgstyle['font-stretch']);
24684: $font_spacing = $this->getCSSFontSpacing($font_spacing, $svgstyle['letter-spacing']);
24685: switch ($font_style) {
24686: case 'italic': {
24687: $font_style = 'I';
24688: break;
24689: }
24690: case 'oblique': {
24691: $font_style = 'I';
24692: break;
24693: }
24694: default:
24695: case 'normal': {
24696: $font_style = '';
24697: break;
24698: }
24699: }
24700: switch ($font_weight) {
24701: case 'bold':
24702: case 'bolder': {
24703: $font_style .= 'B';
24704: break;
24705: }
24706: }
24707: switch ($svgstyle['text-decoration']) {
24708: case 'underline': {
24709: $font_style .= 'U';
24710: break;
24711: }
24712: case 'overline': {
24713: $font_style .= 'O';
24714: break;
24715: }
24716: case 'line-through': {
24717: $font_style .= 'D';
24718: break;
24719: }
24720: default:
24721: case 'none': {
24722: break;
24723: }
24724: }
24725: $this->SetFont($font_family, $font_style, $font_size);
24726: $this->setFontStretching($font_stretch);
24727: $this->setFontSpacing($font_spacing);
24728: return $objstyle;
24729: }
24730:
24731: 24732: 24733: 24734: 24735: 24736: 24737: 24738: 24739: 24740: 24741: 24742: 24743: 24744: 24745: 24746: 24747: 24748:
24749: protected function SVGPath($d, $style='') {
24750:
24751: $op = $this->getPathPaintOperator($style, '');
24752: if (empty($op)) {
24753: return;
24754: }
24755: $paths = array();
24756: $d = str_replace('-', ' -', $d);
24757: $d = str_replace('+', ' +', $d);
24758: preg_match_all('/([a-zA-Z])[\s]*([^a-zA-Z\"]*)/si', $d, $paths, PREG_SET_ORDER);
24759: $x = 0;
24760: $y = 0;
24761: $x1 = 0;
24762: $y1 = 0;
24763: $x2 = 0;
24764: $y2 = 0;
24765: $xmin = 2147483647;
24766: $xmax = 0;
24767: $ymin = 2147483647;
24768: $ymax = 0;
24769: $relcoord = false;
24770:
24771: foreach ($paths as $key => $val) {
24772:
24773: $cmd = trim($val[1]);
24774: if (strtolower($cmd) == $cmd) {
24775:
24776: $relcoord = true;
24777: $xoffset = $x;
24778: $yoffset = $y;
24779: } else {
24780: $relcoord = false;
24781: $xoffset = 0;
24782: $yoffset = 0;
24783: }
24784: $params = array();
24785: if (isset($val[2])) {
24786:
24787: $rawparams = preg_split('/([\,\s]+)/si', trim($val[2]));
24788: $params = array();
24789: foreach ($rawparams as $ck => $cp) {
24790: $params[$ck] = $this->getHTMLUnitToUnits($cp, 0, $this->svgunit, false);
24791: }
24792: }
24793: switch (strtoupper($cmd)) {
24794: case 'M': {
24795: foreach ($params as $ck => $cp) {
24796: if (($ck % 2) == 0) {
24797: $x = $cp + $xoffset;
24798: } else {
24799: $y = $cp + $yoffset;
24800: if ($ck == 1) {
24801: $this->_outPoint($x, $y);
24802: } else {
24803: $this->_outLine($x, $y);
24804: }
24805: $xmin = min($xmin, $x);
24806: $ymin = min($ymin, $y);
24807: $xmax = max($xmax, $x);
24808: $ymax = max($ymax, $y);
24809: if ($relcoord) {
24810: $xoffset = $x;
24811: $yoffset = $y;
24812: }
24813: }
24814: }
24815: break;
24816: }
24817: case 'L': {
24818: foreach ($params as $ck => $cp) {
24819: if (($ck % 2) == 0) {
24820: $x = $cp + $xoffset;
24821: } else {
24822: $y = $cp + $yoffset;
24823: $this->_outLine($x, $y);
24824: $xmin = min($xmin, $x);
24825: $ymin = min($ymin, $y);
24826: $xmax = max($xmax, $x);
24827: $ymax = max($ymax, $y);
24828: if ($relcoord) {
24829: $xoffset = $x;
24830: $yoffset = $y;
24831: }
24832: }
24833: }
24834: break;
24835: }
24836: case 'H': {
24837: foreach ($params as $ck => $cp) {
24838: $x = $cp + $xoffset;
24839: $this->_outLine($x, $y);
24840: $xmin = min($xmin, $x);
24841: $xmax = max($xmax, $x);
24842: if ($relcoord) {
24843: $xoffset = $x;
24844: }
24845: }
24846: break;
24847: }
24848: case 'V': {
24849: foreach ($params as $ck => $cp) {
24850: $y = $cp + $yoffset;
24851: $this->_outLine($x, $y);
24852: $ymin = min($ymin, $y);
24853: $ymax = max($ymax, $y);
24854: if ($relcoord) {
24855: $yoffset = $y;
24856: }
24857: }
24858: break;
24859: }
24860: case 'C': {
24861: foreach ($params as $ck => $cp) {
24862: $params[$ck] = $cp;
24863: if ((($ck + 1) % 6) == 0) {
24864: $x1 = $params[($ck - 5)] + $xoffset;
24865: $y1 = $params[($ck - 4)] + $yoffset;
24866: $x2 = $params[($ck - 3)] + $xoffset;
24867: $y2 = $params[($ck - 2)] + $yoffset;
24868: $x = $params[($ck - 1)] + $xoffset;
24869: $y = $params[($ck)] + $yoffset;
24870: $this->_outCurve($x1, $y1, $x2, $y2, $x, $y);
24871: $xmin = min($xmin, $x, $x1, $x2);
24872: $ymin = min($ymin, $y, $y1, $y2);
24873: $xmax = max($xmax, $x, $x1, $x2);
24874: $ymax = max($ymax, $y, $y1, $y2);
24875: if ($relcoord) {
24876: $xoffset = $x;
24877: $yoffset = $y;
24878: }
24879: }
24880: }
24881: break;
24882: }
24883: case 'S': {
24884: foreach ($params as $ck => $cp) {
24885: $params[$ck] = $cp;
24886: if ((($ck + 1) % 4) == 0) {
24887: if (($key > 0) AND ((strtoupper($paths[($key - 1)][1]) == 'C') OR (strtoupper($paths[($key - 1)][1]) == 'S'))) {
24888: $x1 = (2 * $x) - $x2;
24889: $y1 = (2 * $y) - $y2;
24890: } else {
24891: $x1 = $x;
24892: $y1 = $y;
24893: }
24894: $x2 = $params[($ck - 3)] + $xoffset;
24895: $y2 = $params[($ck - 2)] + $yoffset;
24896: $x = $params[($ck - 1)] + $xoffset;
24897: $y = $params[($ck)] + $yoffset;
24898: $this->_outCurve($x1, $y1, $x2, $y2, $x, $y);
24899: $xmin = min($xmin, $x, $x1, $x2);
24900: $ymin = min($ymin, $y, $y1, $y2);
24901: $xmax = max($xmax, $x, $x1, $x2);
24902: $ymax = max($ymax, $y, $y1, $y2);
24903: if ($relcoord) {
24904: $xoffset = $x;
24905: $yoffset = $y;
24906: }
24907: }
24908: }
24909: break;
24910: }
24911: case 'Q': {
24912: foreach ($params as $ck => $cp) {
24913: $params[$ck] = $cp;
24914: if ((($ck + 1) % 4) == 0) {
24915:
24916: $x1 = $params[($ck - 3)] + $xoffset;
24917: $y1 = $params[($ck - 2)] + $yoffset;
24918: $xa = ($x + (2 * $x1)) / 3;
24919: $ya = ($y + (2 * $y1)) / 3;
24920: $x = $params[($ck - 1)] + $xoffset;
24921: $y = $params[($ck)] + $yoffset;
24922: $xb = ($x + (2 * $x1)) / 3;
24923: $yb = ($y + (2 * $y1)) / 3;
24924: $this->_outCurve($xa, $ya, $xb, $yb, $x, $y);
24925: $xmin = min($xmin, $x, $xa, $xb);
24926: $ymin = min($ymin, $y, $ya, $yb);
24927: $xmax = max($xmax, $x, $xa, $xb);
24928: $ymax = max($ymax, $y, $ya, $yb);
24929: if ($relcoord) {
24930: $xoffset = $x;
24931: $yoffset = $y;
24932: }
24933: }
24934: }
24935: break;
24936: }
24937: case 'T': {
24938: foreach ($params as $ck => $cp) {
24939: $params[$ck] = $cp;
24940: if (($ck % 2) != 0) {
24941: if (($key > 0) AND ((strtoupper($paths[($key - 1)][1]) == 'Q') OR (strtoupper($paths[($key - 1)][1]) == 'T'))) {
24942: $x1 = (2 * $x) - $x1;
24943: $y1 = (2 * $y) - $y1;
24944: } else {
24945: $x1 = $x;
24946: $y1 = $y;
24947: }
24948:
24949: $xa = ($x + (2 * $x1)) / 3;
24950: $ya = ($y + (2 * $y1)) / 3;
24951: $x = $params[($ck - 1)] + $xoffset;
24952: $y = $params[($ck)] + $yoffset;
24953: $xb = ($x + (2 * $x1)) / 3;
24954: $yb = ($y + (2 * $y1)) / 3;
24955: $this->_outCurve($xa, $ya, $xb, $yb, $x, $y);
24956: $xmin = min($xmin, $x, $x1, $x2);
24957: $ymin = min($ymin, $y, $y1, $y2);
24958: $xmax = max($xmax, $x, $x1, $x2);
24959: $ymax = max($ymax, $y, $y1, $y2);
24960: if ($relcoord) {
24961: $xoffset = $x;
24962: $yoffset = $y;
24963: }
24964: }
24965: }
24966: break;
24967: }
24968: case 'A': {
24969: foreach ($params as $ck => $cp) {
24970: $params[$ck] = $cp;
24971: if ((($ck + 1) % 7) == 0) {
24972: $x0 = $x;
24973: $y0 = $y;
24974: $rx = abs($params[($ck - 6)]);
24975: $ry = abs($params[($ck - 5)]);
24976: $ang = -$rawparams[($ck - 4)];
24977: $angle = deg2rad($ang);
24978: $fa = $rawparams[($ck - 3)];
24979: $fs = $rawparams[($ck - 2)];
24980: $x = $params[($ck - 1)] + $xoffset;
24981: $y = $params[$ck] + $yoffset;
24982: $cos_ang = cos($angle);
24983: $sin_ang = sin($angle);
24984: $a = ($x0 - $x) / 2;
24985: $b = ($y0 - $y) / 2;
24986: $xa = ($a * $cos_ang) - ($b * $sin_ang);
24987: $ya = ($a * $sin_ang) + ($b * $cos_ang);
24988: $rx2 = $rx * $rx;
24989: $ry2 = $ry * $ry;
24990: $xa2 = $xa * $xa;
24991: $ya2 = $ya * $ya;
24992: $delta = ($xa2 / $rx2) + ($ya2 / $ry2);
24993: if ($delta > 1) {
24994: $rx *= sqrt($delta);
24995: $ry *= sqrt($delta);
24996: $rx2 = $rx * $rx;
24997: $ry2 = $ry * $ry;
24998: }
24999: $numerator = (($rx2 * $ry2) - ($rx2 * $ya2) - ($ry2 * $xa2));
25000: if ($numerator < 0) {
25001: $root = 0;
25002: } else {
25003: $root = sqrt($numerator / (($rx2 * $ya2) + ($ry2 * $xa2)));
25004: }
25005: if ($fa == $fs) {
25006: $root *= -1;
25007: }
25008: $cax = $root * (($rx * $ya) / $ry);
25009: $cay = -$root * (($ry * $xa) / $rx);
25010:
25011: $cx = ($cax * $cos_ang) - ($cay * $sin_ang) + (($x0 + $x) / 2);
25012: $cy = ($cax * $sin_ang) + ($cay * $cos_ang) + (($y0 + $y) / 2);
25013:
25014: $angs = $this->getVectorsAngle(1, 0, (($xa - $cax) / $rx), (($cay - $ya) / $ry));
25015: $dang = $this->getVectorsAngle((($xa - $cax) / $rx), (($ya - $cay) / $ry), ((-$xa - $cax) / $rx), ((-$ya - $cay) / $ry));
25016: if (($fs == 0) AND ($dang > 0)) {
25017: $dang -= (2 * M_PI);
25018: } elseif (($fs == 1) AND ($dang < 0)) {
25019: $dang += (2 * M_PI);
25020: }
25021: $angf = $angs - $dang;
25022: if (($fs == 1) AND ($angs > $angf)) {
25023: $tmp = $angs;
25024: $angs = $angf;
25025: $angf = $tmp;
25026: }
25027: $angs = rad2deg($angs);
25028: $angf = rad2deg($angf);
25029: $pie = false;
25030: if ((isset($paths[($key + 1)][1])) AND (trim($paths[($key + 1)][1]) == 'z')) {
25031: $pie = true;
25032: }
25033: $this->_outellipticalarc($cx, $cy, $rx, $ry, $ang, $angs, $angf, $pie, 2);
25034: $this->_outPoint($x, $y);
25035: $xmin = min($xmin, $x);
25036: $ymin = min($ymin, $y);
25037: $xmax = max($xmax, $x);
25038: $ymax = max($ymax, $y);
25039: if ($relcoord) {
25040: $xoffset = $x;
25041: $yoffset = $y;
25042: }
25043: }
25044: }
25045: break;
25046: }
25047: case 'Z': {
25048: $this->_out('h');
25049: break;
25050: }
25051: }
25052: }
25053: if (!empty($op)) {
25054: $this->_out($op);
25055: }
25056: return array($xmin, $ymin, ($xmax - $xmin), ($ymax - $ymin));
25057: }
25058:
25059: 25060: 25061: 25062: 25063: 25064: 25065: 25066: 25067: 25068:
25069: protected function getVectorsAngle($x1, $y1, $x2, $y2) {
25070: $dprod = ($x1 * $x2) + ($y1 * $y2);
25071: $dist1 = sqrt(($x1 * $x1) + ($y1 * $y1));
25072: $dist2 = sqrt(($x2 * $x2) + ($y2 * $y2));
25073: $angle = acos($dprod / ($dist1 * $dist2));
25074: if (is_nan($angle)) {
25075: $angle = M_PI;
25076: }
25077: if ((($x1 * $y2) - ($x2 * $y1)) < 0) {
25078: $angle *= -1;
25079: }
25080: return $angle;
25081: }
25082:
25083: 25084: 25085: 25086: 25087: 25088: 25089: 25090: 25091: 25092:
25093: protected function startSVGElementHandler($parser, $name, $attribs, $ctm=array()) {
25094:
25095: if ($this->svgclipmode) {
25096: $this->svgclippaths[$this->svgclipid][] = array('name' => $name, 'attribs' => $attribs, 'tm' => $this->svgcliptm[$this->svgclipid]);
25097: return;
25098: }
25099: if ($this->svgdefsmode AND !in_array($name, array('clipPath', 'linearGradient', 'radialGradient', 'stop'))) {
25100: if (!isset($attribs['id'])) {
25101: $attribs['id'] = 'DF_'.(count($this->svgdefs) + 1);
25102: }
25103: $this->svgdefs[$attribs['id']] = array('name' => $name, 'attribs' => $attribs);
25104: return;
25105: }
25106: $clipping = false;
25107: if ($parser == 'clip-path') {
25108:
25109: $clipping = true;
25110: }
25111:
25112: $prev_svgstyle = $this->svgstyles[(count($this->svgstyles) - 1)];
25113: $svgstyle = $this->svgstyles[0];
25114: if (isset($attribs['style']) AND !$this->empty_string($attribs['style'])) {
25115:
25116: $attribs['style'] = ';'.$attribs['style'];
25117: }
25118: foreach ($prev_svgstyle as $key => $val) {
25119: if (in_array($key, $this->svginheritprop)) {
25120:
25121: $svgstyle[$key] = $val;
25122: }
25123: if (isset($attribs[$key]) AND !$this->empty_string($attribs[$key])) {
25124:
25125: if ($attribs[$key] == 'inherit') {
25126: $svgstyle[$key] = $val;
25127: } else {
25128: $svgstyle[$key] = $attribs[$key];
25129: }
25130: } elseif (isset($attribs['style']) AND !$this->empty_string($attribs['style'])) {
25131:
25132: $attrval = array();
25133: if (preg_match('/[;\"\s]{1}'.$key.'[\s]*:[\s]*([^;\"]*)/si', $attribs['style'], $attrval) AND isset($attrval[1])) {
25134: if ($attrval[1] == 'inherit') {
25135: $svgstyle[$key] = $val;
25136: } else {
25137: $svgstyle[$key] = $attrval[1];
25138: }
25139: }
25140: }
25141: }
25142:
25143: if (!empty($ctm)) {
25144: $tm = $ctm;
25145: } else {
25146: $tm = $this->svgstyles[(count($this->svgstyles) - 1)]['transfmatrix'];
25147: }
25148: if (isset($attribs['transform']) AND !empty($attribs['transform'])) {
25149: $tm = $this->getTransformationMatrixProduct($tm, $this->getSVGTransformMatrix($attribs['transform']));
25150: }
25151: $svgstyle['transfmatrix'] = $tm;
25152: $invisible = false;
25153: if (($svgstyle['visibility'] == 'hidden') OR ($svgstyle['visibility'] == 'collapse') OR ($svgstyle['display'] == 'none')) {
25154:
25155: $invisible = true;
25156: }
25157:
25158: switch($name) {
25159: case 'defs': {
25160: $this->svgdefsmode = true;
25161: break;
25162: }
25163:
25164: case 'clipPath': {
25165: if ($invisible) {
25166: break;
25167: }
25168: $this->svgclipmode = true;
25169: if (!isset($attribs['id'])) {
25170: $attribs['id'] = 'CP_'.(count($this->svgcliptm) + 1);
25171: }
25172: $this->svgclipid = $attribs['id'];
25173: $this->svgclippaths[$this->svgclipid] = array();
25174: $this->svgcliptm[$this->svgclipid] = $tm;
25175: break;
25176: }
25177: case 'svg': {
25178:
25179: break;
25180: }
25181: case 'g': {
25182:
25183: array_push($this->svgstyles, $svgstyle);
25184: $this->StartTransform();
25185: $this->setSVGStyles($svgstyle, $prev_svgstyle);
25186: break;
25187: }
25188: case 'linearGradient': {
25189: if (!isset($attribs['id'])) {
25190: $attribs['id'] = 'GR_'.(count($this->svggradients) + 1);
25191: }
25192: $this->svggradientid = $attribs['id'];
25193: $this->svggradients[$this->svggradientid] = array();
25194: $this->svggradients[$this->svggradientid]['type'] = 2;
25195: $this->svggradients[$this->svggradientid]['stops'] = array();
25196: if (isset($attribs['gradientUnits'])) {
25197: $this->svggradients[$this->svggradientid]['gradientUnits'] = $attribs['gradientUnits'];
25198: } else {
25199: $this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox';
25200: }
25201:
25202: $x1 = (isset($attribs['x1'])?$attribs['x1']:0);
25203: $y1 = (isset($attribs['y1'])?$attribs['y1']:0);
25204: $x2 = (isset($attribs['x2'])?$attribs['x2']:1);
25205: $y2 = (isset($attribs['y2'])?$attribs['y2']:0);
25206: if (isset($attribs['x1']) AND (substr($attribs['x1'], -1) != '%')) {
25207: $this->svggradients[$this->svggradientid]['mode'] = 'measure';
25208: } else {
25209: $this->svggradients[$this->svggradientid]['mode'] = 'percentage';
25210: }
25211: if (isset($attribs['gradientTransform'])) {
25212: $this->svggradients[$this->svggradientid]['gradientTransform'] = $this->getSVGTransformMatrix($attribs['gradientTransform']);
25213: }
25214: $this->svggradients[$this->svggradientid]['coords'] = array($x1, $y1, $x2, $y2);
25215: if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) {
25216:
25217: $this->svggradients[$this->svggradientid]['xref'] = substr($attribs['xlink:href'], 1);
25218: }
25219: break;
25220: }
25221: case 'radialGradient': {
25222: if (!isset($attribs['id'])) {
25223: $attribs['id'] = 'GR_'.(count($this->svggradients) + 1);
25224: }
25225: $this->svggradientid = $attribs['id'];
25226: $this->svggradients[$this->svggradientid] = array();
25227: $this->svggradients[$this->svggradientid]['type'] = 3;
25228: $this->svggradients[$this->svggradientid]['stops'] = array();
25229: if (isset($attribs['gradientUnits'])) {
25230: $this->svggradients[$this->svggradientid]['gradientUnits'] = $attribs['gradientUnits'];
25231: } else {
25232: $this->svggradients[$this->svggradientid]['gradientUnits'] = 'objectBoundingBox';
25233: }
25234:
25235: $cx = (isset($attribs['cx'])?$attribs['cx']:0.5);
25236: $cy = (isset($attribs['cy'])?$attribs['cy']:0.5);
25237: $fx = (isset($attribs['fx'])?$attribs['fx']:$cx);
25238: $fy = (isset($attribs['fy'])?$attribs['fy']:$cy);
25239: $r = (isset($attribs['r'])?$attribs['r']:0.5);
25240: if (isset($attribs['cx']) AND (substr($attribs['cx'], -1) != '%')) {
25241: $this->svggradients[$this->svggradientid]['mode'] = 'measure';
25242: } else {
25243: $this->svggradients[$this->svggradientid]['mode'] = 'percentage';
25244: }
25245: if (isset($attribs['gradientTransform'])) {
25246: $this->svggradients[$this->svggradientid]['gradientTransform'] = $this->getSVGTransformMatrix($attribs['gradientTransform']);
25247: }
25248: $this->svggradients[$this->svggradientid]['coords'] = array($cx, $cy, $fx, $fy, $r);
25249: if (isset($attribs['xlink:href']) AND !empty($attribs['xlink:href'])) {
25250:
25251: $this->svggradients[$this->svggradientid]['xref'] = substr($attribs['xlink:href'], 1);
25252: }
25253: break;
25254: }
25255: case 'stop': {
25256:
25257: if (substr($attribs['offset'], -1) == '%') {
25258: $offset = floatval(substr($attribs['offset'], -1)) / 100;
25259: } else {
25260: $offset = floatval($attribs['offset']);
25261: if ($offset > 1) {
25262: $offset /= 100;
25263: }
25264: }
25265: $stop_color = isset($svgstyle['stop-color'])?$this->convertHTMLColorToDec($svgstyle['stop-color']):'black';
25266: $opacity = isset($svgstyle['stop-opacity'])?$svgstyle['stop-opacity']:1;
25267: $this->svggradients[$this->svggradientid]['stops'][] = array('offset' => $offset, 'color' => $stop_color, 'opacity' => $opacity);
25268: break;
25269: }
25270:
25271: case 'path': {
25272: if ($invisible) {
25273: break;
25274: }
25275: $d = trim($attribs['d']);
25276: if ($clipping) {
25277: $this->SVGTransform($tm);
25278: $this->SVGPath($d, 'CNZ');
25279: } else {
25280: $this->StartTransform();
25281: $this->SVGTransform($tm);
25282: $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, 0, 0, 1, 1, 'SVGPath', array($d, 'CNZ'));
25283: if (!empty($obstyle)) {
25284: $this->SVGPath($d, $obstyle);
25285: }
25286: $this->StopTransform();
25287: }
25288: break;
25289: }
25290:
25291: case 'rect': {
25292: if ($invisible) {
25293: break;
25294: }
25295: $x = (isset($attribs['x'])?$this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false):0);
25296: $y = (isset($attribs['y'])?$this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false):0);
25297: $w = (isset($attribs['width'])?$this->getHTMLUnitToUnits($attribs['width'], 0, $this->svgunit, false):0);
25298: $h = (isset($attribs['height'])?$this->getHTMLUnitToUnits($attribs['height'], 0, $this->svgunit, false):0);
25299: $rx = (isset($attribs['rx'])?$this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false):0);
25300: $ry = (isset($attribs['ry'])?$this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false):$rx);
25301: if ($clipping) {
25302: $this->SVGTransform($tm);
25303: $this->RoundedRectXY($x, $y, $w, $h, $rx, $ry, '1111', 'CNZ', array(), array());
25304: } else {
25305: $this->StartTransform();
25306: $this->SVGTransform($tm);
25307: $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'RoundedRectXY', array($x, $y, $w, $h, $rx, $ry, '1111', 'CNZ'));
25308: if (!empty($obstyle)) {
25309: $this->RoundedRectXY($x, $y, $w, $h, $rx, $ry, '1111', $obstyle, array(), array());
25310: }
25311: $this->StopTransform();
25312: }
25313: break;
25314: }
25315: case 'circle': {
25316: if ($invisible) {
25317: break;
25318: }
25319: $cx = (isset($attribs['cx'])?$this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false):0);
25320: $cy = (isset($attribs['cy'])?$this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false):0);
25321: $r = (isset($attribs['r'])?$this->getHTMLUnitToUnits($attribs['r'], 0, $this->svgunit, false):0);
25322: $x = $cx - $r;
25323: $y = $cy - $r;
25324: $w = 2 * $r;
25325: $h = $w;
25326: if ($clipping) {
25327: $this->SVGTransform($tm);
25328: $this->Circle($cx, $cy, $r, 0, 360, 'CNZ', array(), array(), 8);
25329: } else {
25330: $this->StartTransform();
25331: $this->SVGTransform($tm);
25332: $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Circle', array($cx, $cy, $r, 0, 360, 'CNZ'));
25333: if (!empty($obstyle)) {
25334: $this->Circle($cx, $cy, $r, 0, 360, $obstyle, array(), array(), 8);
25335: }
25336: $this->StopTransform();
25337: }
25338: break;
25339: }
25340: case 'ellipse': {
25341: if ($invisible) {
25342: break;
25343: }
25344: $cx = (isset($attribs['cx'])?$this->getHTMLUnitToUnits($attribs['cx'], 0, $this->svgunit, false):0);
25345: $cy = (isset($attribs['cy'])?$this->getHTMLUnitToUnits($attribs['cy'], 0, $this->svgunit, false):0);
25346: $rx = (isset($attribs['rx'])?$this->getHTMLUnitToUnits($attribs['rx'], 0, $this->svgunit, false):0);
25347: $ry = (isset($attribs['ry'])?$this->getHTMLUnitToUnits($attribs['ry'], 0, $this->svgunit, false):0);
25348: $x = $cx - $rx;
25349: $y = $cy - $ry;
25350: $w = 2 * $rx;
25351: $h = 2 * $ry;
25352: if ($clipping) {
25353: $this->SVGTransform($tm);
25354: $this->Ellipse($cx, $cy, $rx, $ry, 0, 0, 360, 'CNZ', array(), array(), 8);
25355: } else {
25356: $this->StartTransform();
25357: $this->SVGTransform($tm);
25358: $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Ellipse', array($cx, $cy, $rx, $ry, 0, 0, 360, 'CNZ'));
25359: if (!empty($obstyle)) {
25360: $this->Ellipse($cx, $cy, $rx, $ry, 0, 0, 360, $obstyle, array(), array(), 8);
25361: }
25362: $this->StopTransform();
25363: }
25364: break;
25365: }
25366: case 'line': {
25367: if ($invisible) {
25368: break;
25369: }
25370: $x1 = (isset($attribs['x1'])?$this->getHTMLUnitToUnits($attribs['x1'], 0, $this->svgunit, false):0);
25371: $y1 = (isset($attribs['y1'])?$this->getHTMLUnitToUnits($attribs['y1'], 0, $this->svgunit, false):0);
25372: $x2 = (isset($attribs['x2'])?$this->getHTMLUnitToUnits($attribs['x2'], 0, $this->svgunit, false):0);
25373: $y2 = (isset($attribs['y2'])?$this->getHTMLUnitToUnits($attribs['y2'], 0, $this->svgunit, false):0);
25374: $x = $x1;
25375: $y = $y1;
25376: $w = abs($x2 - $x1);
25377: $h = abs($y2 - $y1);
25378: if (!$clipping) {
25379: $this->StartTransform();
25380: $this->SVGTransform($tm);
25381: $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Line', array($x1, $y1, $x2, $y2));
25382: $this->Line($x1, $y1, $x2, $y2);
25383: $this->StopTransform();
25384: }
25385: break;
25386: }
25387: case 'polyline':
25388: case 'polygon': {
25389: if ($invisible) {
25390: break;
25391: }
25392: $points = (isset($attribs['points'])?$attribs['points']:'0 0');
25393: $points = trim($points);
25394:
25395: $points = preg_split('/[\,\s]+/si', $points);
25396: if (count($points) < 4) {
25397: break;
25398: }
25399: $p = array();
25400: $xmin = 2147483647;
25401: $xmax = 0;
25402: $ymin = 2147483647;
25403: $ymax = 0;
25404: foreach ($points as $key => $val) {
25405: $p[$key] = $this->getHTMLUnitToUnits($val, 0, $this->svgunit, false);
25406: if (($key % 2) == 0) {
25407:
25408: $xmin = min($xmin, $p[$key]);
25409: $xmax = max($xmax, $p[$key]);
25410: } else {
25411:
25412: $ymin = min($ymin, $p[$key]);
25413: $ymax = max($ymax, $p[$key]);
25414: }
25415: }
25416: $x = $xmin;
25417: $y = $ymin;
25418: $w = ($xmax - $xmin);
25419: $h = ($ymax - $ymin);
25420: if ($name == 'polyline') {
25421: $this->StartTransform();
25422: $this->SVGTransform($tm);
25423: $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'PolyLine', array($p, 'CNZ'));
25424: $this->PolyLine($p, 'D', array(), array());
25425: $this->StopTransform();
25426: } else {
25427: if ($clipping) {
25428: $this->SVGTransform($tm);
25429: $this->Polygon($p, 'CNZ', array(), array(), true);
25430: } else {
25431: $this->StartTransform();
25432: $this->SVGTransform($tm);
25433: $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h, 'Polygon', array($p, 'CNZ'));
25434: if (!empty($obstyle)) {
25435: $this->Polygon($p, $obstyle, array(), array(), true);
25436: }
25437: $this->StopTransform();
25438: }
25439: }
25440: break;
25441: }
25442:
25443: case 'image': {
25444: if ($invisible) {
25445: break;
25446: }
25447: if (!isset($attribs['xlink:href']) OR empty($attribs['xlink:href'])) {
25448: break;
25449: }
25450: $x = (isset($attribs['x'])?$this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false):0);
25451: $y = (isset($attribs['y'])?$this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false):0);
25452: $w = (isset($attribs['width'])?$this->getHTMLUnitToUnits($attribs['width'], 0, $this->svgunit, false):0);
25453: $h = (isset($attribs['height'])?$this->getHTMLUnitToUnits($attribs['height'], 0, $this->svgunit, false):0);
25454: $img = $attribs['xlink:href'];
25455: if (!$clipping) {
25456: $this->StartTransform();
25457: $this->SVGTransform($tm);
25458: $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, $w, $h);
25459:
25460: if (!$this->empty_string($this->svgdir) AND (($img{0} == '.') OR (basename($img) == $img))) {
25461:
25462: $img = $this->svgdir.'/'.$img;
25463: }
25464: if (($img{0} == '/') AND ($_SERVER['DOCUMENT_ROOT'] != '/')) {
25465: $findroot = strpos($img, $_SERVER['DOCUMENT_ROOT']);
25466: if (($findroot === false) OR ($findroot > 1)) {
25467:
25468: $img = $_SERVER['DOCUMENT_ROOT'].$img;
25469: }
25470: }
25471: $img = urldecode($img);
25472: $testscrtype = @parse_url($img);
25473: if (!isset($testscrtype['query']) OR empty($testscrtype['query'])) {
25474:
25475: $img = str_replace(K_PATH_URL, K_PATH_MAIN, $img);
25476: }
25477: $this->Image($img, $x, $y, $w, $h);
25478: $this->StopTransform();
25479: }
25480: break;
25481: }
25482:
25483: case 'text':
25484: case 'tspan': {
25485: $this->svgtextmode['invisible'] = $invisible;
25486: if ($invisible) {
25487: break;
25488: }
25489: array_push($this->svgstyles, $svgstyle);
25490:
25491: $x = (isset($attribs['x'])?$this->getHTMLUnitToUnits($attribs['x'], 0, $this->svgunit, false):$this->x);
25492: $y = (isset($attribs['y'])?$this->getHTMLUnitToUnits($attribs['y'], 0, $this->svgunit, false):$this->y);
25493: $svgstyle['text-color'] = $svgstyle['fill'];
25494: $this->svgtext = '';
25495: if (isset($svgstyle['text-anchor'])) {
25496: $this->svgtextmode['text-anchor'] = $svgstyle['text-anchor'];
25497: } else {
25498: $this->svgtextmode['text-anchor'] = 'start';
25499: }
25500: if (isset($svgstyle['direction'])) {
25501: if ($svgstyle['direction'] == 'rtl') {
25502: $this->svgtextmode['rtl'] = true;
25503: } else {
25504: $this->svgtextmode['rtl'] = false;
25505: }
25506: } else {
25507: $this->svgtextmode['rtl'] = false;
25508: }
25509: if (isset($svgstyle['stroke']) AND ($svgstyle['stroke'] != 'none') AND isset($svgstyle['stroke-width']) AND ($svgstyle['stroke-width'] > 0)) {
25510: $this->svgtextmode['stroke'] = $this->getHTMLUnitToUnits($svgstyle['stroke-width'], 0, $this->svgunit, false);
25511: } else {
25512: $this->svgtextmode['stroke'] = false;
25513: }
25514: $this->StartTransform();
25515: $this->SVGTransform($tm);
25516: $obstyle = $this->setSVGStyles($svgstyle, $prev_svgstyle, $x, $y, 1, 1);
25517: $this->x = $x;
25518: $this->y = $y;
25519: break;
25520: }
25521:
25522: case 'use': {
25523: if (isset($attribs['xlink:href'])) {
25524: $use = $this->svgdefs[substr($attribs['xlink:href'], 1)];
25525: if (isset($attribs['xlink:href'])) {
25526: unset($attribs['xlink:href']);
25527: }
25528: if (isset($attribs['id'])) {
25529: unset($attribs['id']);
25530: }
25531: $attribs = array_merge($use['attribs'], $attribs);
25532: $this->startSVGElementHandler($parser, $use['name'], $use['attribs']);
25533: }
25534: break;
25535: }
25536: default: {
25537: break;
25538: }
25539: }
25540: }
25541:
25542: 25543: 25544: 25545: 25546: 25547: 25548: 25549:
25550: protected function endSVGElementHandler($parser, $name) {
25551: switch($name) {
25552: case 'defs': {
25553: $this->svgdefsmode = false;
25554: break;
25555: }
25556:
25557: case 'clipPath': {
25558: $this->svgclipmode = false;
25559: break;
25560: }
25561: case 'g': {
25562:
25563: array_pop($this->svgstyles);
25564: $this->StopTransform();
25565: break;
25566: }
25567: case 'text':
25568: case 'tspan': {
25569: if ($this->svgtextmode['invisible']) {
25570:
25571:
25572: break;
25573: }
25574:
25575: $text = $this->stringTrim($this->svgtext);
25576: if ($this->svgtextmode['text-anchor'] != 'start') {
25577: $textlen = $this->GetStringWidth($text);
25578:
25579: if ($this->svgtextmode['text-anchor'] == 'end') {
25580: if ($this->svgtextmode['rtl']) {
25581: $this->x += $textlen;
25582: } else {
25583: $this->x -= $textlen;
25584: }
25585: } elseif ($this->svgtextmode['text-anchor'] == 'middle') {
25586: if ($this->svgtextmode['rtl']) {
25587: $this->x += ($textlen / 2);
25588: } else {
25589: $this->x -= ($textlen / 2);
25590: }
25591: }
25592: }
25593: $textrendermode = $this->textrendermode;
25594: $textstrokewidth = $this->textstrokewidth;
25595: $this->setTextRenderingMode($this->svgtextmode['stroke'], true, false);
25596: $this->Cell(0, 0, $text, 0, 0, '', false, '', 0, false, 'L', 'T');
25597:
25598: $this->textrendermode = $textrendermode;
25599: $this->textstrokewidth = $textstrokewidth;
25600: $this->svgtext = '';
25601: $this->StopTransform();
25602: array_pop($this->svgstyles);
25603: break;
25604: }
25605: default: {
25606: break;
25607: }
25608: }
25609: }
25610:
25611: 25612: 25613: 25614: 25615: 25616: 25617: 25618:
25619: protected function segSVGContentHandler($parser, $data) {
25620: $this->svgtext .= $data;
25621: }
25622:
25623:
25624:
25625: }
25626:
25627:
25628:
25629:
25630: